2010-12-15 16:49:55 +00:00
|
|
|
// Copyright 2010 The Go Authors. All rights reserved.
|
|
|
|
// Use of this source code is governed by a BSD-style
|
|
|
|
// license that can be found in the LICENSE file.
|
|
|
|
|
|
|
|
package tls
|
|
|
|
|
|
|
|
import (
|
|
|
|
"crypto/aes"
|
|
|
|
"crypto/cipher"
|
2011-10-11 18:07:32 +01:00
|
|
|
"crypto/des"
|
2010-12-15 16:49:55 +00:00
|
|
|
"crypto/hmac"
|
|
|
|
"crypto/rc4"
|
2011-09-14 20:32:19 +01:00
|
|
|
"crypto/sha1"
|
2016-08-18 00:45:47 +01:00
|
|
|
"crypto/sha256"
|
2010-12-16 22:10:50 +00:00
|
|
|
"crypto/x509"
|
2010-12-15 16:49:55 +00:00
|
|
|
"hash"
|
|
|
|
)
|
|
|
|
|
2010-12-16 22:10:50 +00:00
|
|
|
// a keyAgreement implements the client and server side of a TLS key agreement
|
|
|
|
// protocol by generating and processing key exchange messages.
|
|
|
|
type keyAgreement interface {
|
|
|
|
// On the server side, the first two methods are called in order.
|
|
|
|
|
|
|
|
// In the case that the key agreement protocol doesn't use a
|
|
|
|
// ServerKeyExchange message, generateServerKeyExchange can return nil,
|
|
|
|
// nil.
|
2012-04-12 17:35:21 +01:00
|
|
|
generateServerKeyExchange(*Config, *Certificate, *clientHelloMsg, *serverHelloMsg) (*serverKeyExchangeMsg, error)
|
|
|
|
processClientKeyExchange(*Config, *Certificate, *clientKeyExchangeMsg, uint16) ([]byte, error)
|
2010-12-16 22:10:50 +00:00
|
|
|
|
|
|
|
// On the client side, the next two methods are called in order.
|
|
|
|
|
|
|
|
// This method may not be called if the server doesn't send a
|
|
|
|
// ServerKeyExchange message.
|
2011-11-02 02:04:37 +00:00
|
|
|
processServerKeyExchange(*Config, *clientHelloMsg, *serverHelloMsg, *x509.Certificate, *serverKeyExchangeMsg) error
|
|
|
|
generateClientKeyExchange(*Config, *clientHelloMsg, *x509.Certificate) ([]byte, *clientKeyExchangeMsg, error)
|
2010-12-16 22:10:50 +00:00
|
|
|
}
|
|
|
|
|
2013-09-17 18:30:36 +01:00
|
|
|
const (
|
|
|
|
// suiteECDH indicates that the cipher suite involves elliptic curve
|
|
|
|
// Diffie-Hellman. This means that it should only be selected when the
|
|
|
|
// client indicates that it supports ECC with a curve and point format
|
|
|
|
// that we're happy with.
|
|
|
|
suiteECDHE = 1 << iota
|
|
|
|
// suiteECDSA indicates that the cipher suite involves an ECDSA
|
|
|
|
// signature and therefore may only be selected when the server's
|
|
|
|
// certificate is ECDSA. If this is not set then the cipher suite is
|
|
|
|
// RSA based.
|
|
|
|
suiteECDSA
|
2013-09-26 22:09:56 +01:00
|
|
|
// suiteTLS12 indicates that the cipher suite should only be advertised
|
|
|
|
// and accepted when using TLS 1.2.
|
|
|
|
suiteTLS12
|
crypto/tls: decouple handshake signatures from the handshake hash.
Prior to TLS 1.2, the handshake had a pleasing property that one could
incrementally hash it and, from that, get the needed hashes for both
the CertificateVerify and Finished messages.
TLS 1.2 introduced negotiation for the signature and hash and it became
possible for the handshake hash to be, say, SHA-384, but for the
CertificateVerify to sign the handshake with SHA-1. The problem is that
one doesn't know in advance which hashes will be needed and thus the
handshake needs to be buffered.
Go ignored this, always kept a single handshake hash, and any signatures
over the handshake had to use that hash.
However, there are a set of servers that inspect the client's offered
signature hash functions and will abort the handshake if one of the
server's certificates is signed with a hash function outside of that
set. https://robertsspaceindustries.com/ is an example of such a server.
Clearly not a lot of thought happened when that server code was written,
but its out there and we have to deal with it.
This change decouples the handshake hash from the CertificateVerify
hash. This lays the groundwork for advertising support for SHA-384 but
doesn't actually make that change in the interests of reviewability.
Updating the advertised hash functions will cause changes in many of the
testdata/ files and some errors might get lost in the noise. This change
only needs to update four testdata/ files: one because a SHA-384-based
handshake is now being signed with SHA-256 and the others because the
TLS 1.2 CertificateRequest message now includes SHA-1.
This change also has the effect of adding support for
client-certificates in SSLv3 servers. However, SSLv3 is now disabled by
default so this should be moot.
It would be possible to avoid much of this change and just support
SHA-384 for the ServerKeyExchange as the SKX only signs over the nonces
and SKX params (a design mistake in TLS). However, that would leave Go
in the odd situation where it advertised support for SHA-384, but would
only use the handshake hash when signing client certificates. I fear
that'll just cause problems in the future.
Much of this code was written by davidben@ for the purposes of testing
BoringSSL.
Partly addresses #9757
Change-Id: I5137a472b6076812af387a5a69fc62c7373cd485
Reviewed-on: https://go-review.googlesource.com/9415
Run-TryBot: Adam Langley <agl@golang.org>
Reviewed-by: Adam Langley <agl@golang.org>
2015-04-28 17:13:38 +01:00
|
|
|
// suiteSHA384 indicates that the cipher suite uses SHA384 as the
|
|
|
|
// handshake hash.
|
|
|
|
suiteSHA384
|
2015-03-17 00:13:10 +00:00
|
|
|
// suiteDefaultOff indicates that this cipher suite is not included by
|
|
|
|
// default.
|
|
|
|
suiteDefaultOff
|
2013-09-17 18:30:36 +01:00
|
|
|
)
|
|
|
|
|
2010-12-15 16:49:55 +00:00
|
|
|
// A cipherSuite is a specific combination of key agreement, cipher and MAC
|
|
|
|
// function. All cipher suites currently assume RSA key agreement.
|
|
|
|
type cipherSuite struct {
|
2011-11-28 20:34:16 +00:00
|
|
|
id uint16
|
2010-12-15 16:49:55 +00:00
|
|
|
// the lengths, in bytes, of the key material needed for each component.
|
2010-12-15 18:58:57 +00:00
|
|
|
keyLen int
|
|
|
|
macLen int
|
|
|
|
ivLen int
|
2013-07-03 00:58:56 +01:00
|
|
|
ka func(version uint16) keyAgreement
|
2013-09-17 18:30:36 +01:00
|
|
|
// flags is a bitmask of the suite* values, above.
|
crypto/tls: decouple handshake signatures from the handshake hash.
Prior to TLS 1.2, the handshake had a pleasing property that one could
incrementally hash it and, from that, get the needed hashes for both
the CertificateVerify and Finished messages.
TLS 1.2 introduced negotiation for the signature and hash and it became
possible for the handshake hash to be, say, SHA-384, but for the
CertificateVerify to sign the handshake with SHA-1. The problem is that
one doesn't know in advance which hashes will be needed and thus the
handshake needs to be buffered.
Go ignored this, always kept a single handshake hash, and any signatures
over the handshake had to use that hash.
However, there are a set of servers that inspect the client's offered
signature hash functions and will abort the handshake if one of the
server's certificates is signed with a hash function outside of that
set. https://robertsspaceindustries.com/ is an example of such a server.
Clearly not a lot of thought happened when that server code was written,
but its out there and we have to deal with it.
This change decouples the handshake hash from the CertificateVerify
hash. This lays the groundwork for advertising support for SHA-384 but
doesn't actually make that change in the interests of reviewability.
Updating the advertised hash functions will cause changes in many of the
testdata/ files and some errors might get lost in the noise. This change
only needs to update four testdata/ files: one because a SHA-384-based
handshake is now being signed with SHA-256 and the others because the
TLS 1.2 CertificateRequest message now includes SHA-1.
This change also has the effect of adding support for
client-certificates in SSLv3 servers. However, SSLv3 is now disabled by
default so this should be moot.
It would be possible to avoid much of this change and just support
SHA-384 for the ServerKeyExchange as the SKX only signs over the nonces
and SKX params (a design mistake in TLS). However, that would leave Go
in the odd situation where it advertised support for SHA-384, but would
only use the handshake hash when signing client certificates. I fear
that'll just cause problems in the future.
Much of this code was written by davidben@ for the purposes of testing
BoringSSL.
Partly addresses #9757
Change-Id: I5137a472b6076812af387a5a69fc62c7373cd485
Reviewed-on: https://go-review.googlesource.com/9415
Run-TryBot: Adam Langley <agl@golang.org>
Reviewed-by: Adam Langley <agl@golang.org>
2015-04-28 17:13:38 +01:00
|
|
|
flags int
|
|
|
|
cipher func(key, iv []byte, isRead bool) interface{}
|
|
|
|
mac func(version uint16, macKey []byte) macFunction
|
|
|
|
aead func(key, fixedNonce []byte) cipher.AEAD
|
2010-12-15 16:49:55 +00:00
|
|
|
}
|
|
|
|
|
2011-11-28 20:34:16 +00:00
|
|
|
var cipherSuites = []*cipherSuite{
|
2016-08-18 00:45:47 +01:00
|
|
|
// Ciphersuite order is chosen so that ECDHE comes before plain RSA and
|
|
|
|
// GCM is top preference.
|
crypto/tls: decouple handshake signatures from the handshake hash.
Prior to TLS 1.2, the handshake had a pleasing property that one could
incrementally hash it and, from that, get the needed hashes for both
the CertificateVerify and Finished messages.
TLS 1.2 introduced negotiation for the signature and hash and it became
possible for the handshake hash to be, say, SHA-384, but for the
CertificateVerify to sign the handshake with SHA-1. The problem is that
one doesn't know in advance which hashes will be needed and thus the
handshake needs to be buffered.
Go ignored this, always kept a single handshake hash, and any signatures
over the handshake had to use that hash.
However, there are a set of servers that inspect the client's offered
signature hash functions and will abort the handshake if one of the
server's certificates is signed with a hash function outside of that
set. https://robertsspaceindustries.com/ is an example of such a server.
Clearly not a lot of thought happened when that server code was written,
but its out there and we have to deal with it.
This change decouples the handshake hash from the CertificateVerify
hash. This lays the groundwork for advertising support for SHA-384 but
doesn't actually make that change in the interests of reviewability.
Updating the advertised hash functions will cause changes in many of the
testdata/ files and some errors might get lost in the noise. This change
only needs to update four testdata/ files: one because a SHA-384-based
handshake is now being signed with SHA-256 and the others because the
TLS 1.2 CertificateRequest message now includes SHA-1.
This change also has the effect of adding support for
client-certificates in SSLv3 servers. However, SSLv3 is now disabled by
default so this should be moot.
It would be possible to avoid much of this change and just support
SHA-384 for the ServerKeyExchange as the SKX only signs over the nonces
and SKX params (a design mistake in TLS). However, that would leave Go
in the odd situation where it advertised support for SHA-384, but would
only use the handshake hash when signing client certificates. I fear
that'll just cause problems in the future.
Much of this code was written by davidben@ for the purposes of testing
BoringSSL.
Partly addresses #9757
Change-Id: I5137a472b6076812af387a5a69fc62c7373cd485
Reviewed-on: https://go-review.googlesource.com/9415
Run-TryBot: Adam Langley <agl@golang.org>
Reviewed-by: Adam Langley <agl@golang.org>
2015-04-28 17:13:38 +01:00
|
|
|
{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 16, 0, 4, ecdheRSAKA, suiteECDHE | suiteTLS12, nil, nil, aeadAESGCM},
|
|
|
|
{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 16, 0, 4, ecdheECDSAKA, suiteECDHE | suiteECDSA | suiteTLS12, nil, nil, aeadAESGCM},
|
|
|
|
{TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, 32, 0, 4, ecdheRSAKA, suiteECDHE | suiteTLS12 | suiteSHA384, nil, nil, aeadAESGCM},
|
|
|
|
{TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, 32, 0, 4, ecdheECDSAKA, suiteECDHE | suiteECDSA | suiteTLS12 | suiteSHA384, nil, nil, aeadAESGCM},
|
2016-08-18 00:45:47 +01:00
|
|
|
{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, 16, 32, 16, ecdheRSAKA, suiteECDHE | suiteTLS12, cipherAES, macSHA256, nil},
|
crypto/tls: decouple handshake signatures from the handshake hash.
Prior to TLS 1.2, the handshake had a pleasing property that one could
incrementally hash it and, from that, get the needed hashes for both
the CertificateVerify and Finished messages.
TLS 1.2 introduced negotiation for the signature and hash and it became
possible for the handshake hash to be, say, SHA-384, but for the
CertificateVerify to sign the handshake with SHA-1. The problem is that
one doesn't know in advance which hashes will be needed and thus the
handshake needs to be buffered.
Go ignored this, always kept a single handshake hash, and any signatures
over the handshake had to use that hash.
However, there are a set of servers that inspect the client's offered
signature hash functions and will abort the handshake if one of the
server's certificates is signed with a hash function outside of that
set. https://robertsspaceindustries.com/ is an example of such a server.
Clearly not a lot of thought happened when that server code was written,
but its out there and we have to deal with it.
This change decouples the handshake hash from the CertificateVerify
hash. This lays the groundwork for advertising support for SHA-384 but
doesn't actually make that change in the interests of reviewability.
Updating the advertised hash functions will cause changes in many of the
testdata/ files and some errors might get lost in the noise. This change
only needs to update four testdata/ files: one because a SHA-384-based
handshake is now being signed with SHA-256 and the others because the
TLS 1.2 CertificateRequest message now includes SHA-1.
This change also has the effect of adding support for
client-certificates in SSLv3 servers. However, SSLv3 is now disabled by
default so this should be moot.
It would be possible to avoid much of this change and just support
SHA-384 for the ServerKeyExchange as the SKX only signs over the nonces
and SKX params (a design mistake in TLS). However, that would leave Go
in the odd situation where it advertised support for SHA-384, but would
only use the handshake hash when signing client certificates. I fear
that'll just cause problems in the future.
Much of this code was written by davidben@ for the purposes of testing
BoringSSL.
Partly addresses #9757
Change-Id: I5137a472b6076812af387a5a69fc62c7373cd485
Reviewed-on: https://go-review.googlesource.com/9415
Run-TryBot: Adam Langley <agl@golang.org>
Reviewed-by: Adam Langley <agl@golang.org>
2015-04-28 17:13:38 +01:00
|
|
|
{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, 16, 20, 16, ecdheRSAKA, suiteECDHE, cipherAES, macSHA1, nil},
|
2016-08-18 00:45:47 +01:00
|
|
|
{TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, 16, 32, 16, ecdheECDSAKA, suiteECDHE | suiteECDSA | suiteTLS12, cipherAES, macSHA256, nil},
|
crypto/tls: decouple handshake signatures from the handshake hash.
Prior to TLS 1.2, the handshake had a pleasing property that one could
incrementally hash it and, from that, get the needed hashes for both
the CertificateVerify and Finished messages.
TLS 1.2 introduced negotiation for the signature and hash and it became
possible for the handshake hash to be, say, SHA-384, but for the
CertificateVerify to sign the handshake with SHA-1. The problem is that
one doesn't know in advance which hashes will be needed and thus the
handshake needs to be buffered.
Go ignored this, always kept a single handshake hash, and any signatures
over the handshake had to use that hash.
However, there are a set of servers that inspect the client's offered
signature hash functions and will abort the handshake if one of the
server's certificates is signed with a hash function outside of that
set. https://robertsspaceindustries.com/ is an example of such a server.
Clearly not a lot of thought happened when that server code was written,
but its out there and we have to deal with it.
This change decouples the handshake hash from the CertificateVerify
hash. This lays the groundwork for advertising support for SHA-384 but
doesn't actually make that change in the interests of reviewability.
Updating the advertised hash functions will cause changes in many of the
testdata/ files and some errors might get lost in the noise. This change
only needs to update four testdata/ files: one because a SHA-384-based
handshake is now being signed with SHA-256 and the others because the
TLS 1.2 CertificateRequest message now includes SHA-1.
This change also has the effect of adding support for
client-certificates in SSLv3 servers. However, SSLv3 is now disabled by
default so this should be moot.
It would be possible to avoid much of this change and just support
SHA-384 for the ServerKeyExchange as the SKX only signs over the nonces
and SKX params (a design mistake in TLS). However, that would leave Go
in the odd situation where it advertised support for SHA-384, but would
only use the handshake hash when signing client certificates. I fear
that'll just cause problems in the future.
Much of this code was written by davidben@ for the purposes of testing
BoringSSL.
Partly addresses #9757
Change-Id: I5137a472b6076812af387a5a69fc62c7373cd485
Reviewed-on: https://go-review.googlesource.com/9415
Run-TryBot: Adam Langley <agl@golang.org>
Reviewed-by: Adam Langley <agl@golang.org>
2015-04-28 17:13:38 +01:00
|
|
|
{TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, 16, 20, 16, ecdheECDSAKA, suiteECDHE | suiteECDSA, cipherAES, macSHA1, nil},
|
|
|
|
{TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, 32, 20, 16, ecdheRSAKA, suiteECDHE, cipherAES, macSHA1, nil},
|
|
|
|
{TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, 32, 20, 16, ecdheECDSAKA, suiteECDHE | suiteECDSA, cipherAES, macSHA1, nil},
|
2015-11-15 00:53:03 +00:00
|
|
|
{TLS_RSA_WITH_AES_128_GCM_SHA256, 16, 0, 4, rsaKA, suiteTLS12, nil, nil, aeadAESGCM},
|
|
|
|
{TLS_RSA_WITH_AES_256_GCM_SHA384, 32, 0, 4, rsaKA, suiteTLS12 | suiteSHA384, nil, nil, aeadAESGCM},
|
2016-08-18 00:45:47 +01:00
|
|
|
{TLS_RSA_WITH_AES_128_CBC_SHA256, 16, 32, 16, rsaKA, suiteTLS12, cipherAES, macSHA256, nil},
|
crypto/tls: decouple handshake signatures from the handshake hash.
Prior to TLS 1.2, the handshake had a pleasing property that one could
incrementally hash it and, from that, get the needed hashes for both
the CertificateVerify and Finished messages.
TLS 1.2 introduced negotiation for the signature and hash and it became
possible for the handshake hash to be, say, SHA-384, but for the
CertificateVerify to sign the handshake with SHA-1. The problem is that
one doesn't know in advance which hashes will be needed and thus the
handshake needs to be buffered.
Go ignored this, always kept a single handshake hash, and any signatures
over the handshake had to use that hash.
However, there are a set of servers that inspect the client's offered
signature hash functions and will abort the handshake if one of the
server's certificates is signed with a hash function outside of that
set. https://robertsspaceindustries.com/ is an example of such a server.
Clearly not a lot of thought happened when that server code was written,
but its out there and we have to deal with it.
This change decouples the handshake hash from the CertificateVerify
hash. This lays the groundwork for advertising support for SHA-384 but
doesn't actually make that change in the interests of reviewability.
Updating the advertised hash functions will cause changes in many of the
testdata/ files and some errors might get lost in the noise. This change
only needs to update four testdata/ files: one because a SHA-384-based
handshake is now being signed with SHA-256 and the others because the
TLS 1.2 CertificateRequest message now includes SHA-1.
This change also has the effect of adding support for
client-certificates in SSLv3 servers. However, SSLv3 is now disabled by
default so this should be moot.
It would be possible to avoid much of this change and just support
SHA-384 for the ServerKeyExchange as the SKX only signs over the nonces
and SKX params (a design mistake in TLS). However, that would leave Go
in the odd situation where it advertised support for SHA-384, but would
only use the handshake hash when signing client certificates. I fear
that'll just cause problems in the future.
Much of this code was written by davidben@ for the purposes of testing
BoringSSL.
Partly addresses #9757
Change-Id: I5137a472b6076812af387a5a69fc62c7373cd485
Reviewed-on: https://go-review.googlesource.com/9415
Run-TryBot: Adam Langley <agl@golang.org>
Reviewed-by: Adam Langley <agl@golang.org>
2015-04-28 17:13:38 +01:00
|
|
|
{TLS_RSA_WITH_AES_128_CBC_SHA, 16, 20, 16, rsaKA, 0, cipherAES, macSHA1, nil},
|
|
|
|
{TLS_RSA_WITH_AES_256_CBC_SHA, 32, 20, 16, rsaKA, 0, cipherAES, macSHA1, nil},
|
|
|
|
{TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, 24, 20, 8, ecdheRSAKA, suiteECDHE, cipher3DES, macSHA1, nil},
|
|
|
|
{TLS_RSA_WITH_3DES_EDE_CBC_SHA, 24, 20, 8, rsaKA, 0, cipher3DES, macSHA1, nil},
|
2016-08-18 00:45:47 +01:00
|
|
|
|
|
|
|
// RC4-based cipher suites are disabled by default.
|
|
|
|
{TLS_RSA_WITH_RC4_128_SHA, 16, 20, 0, rsaKA, suiteDefaultOff, cipherRC4, macSHA1, nil},
|
|
|
|
{TLS_ECDHE_RSA_WITH_RC4_128_SHA, 16, 20, 0, ecdheRSAKA, suiteECDHE | suiteDefaultOff, cipherRC4, macSHA1, nil},
|
|
|
|
{TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, 16, 20, 0, ecdheECDSAKA, suiteECDHE | suiteECDSA | suiteDefaultOff, cipherRC4, macSHA1, nil},
|
2010-12-15 16:49:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func cipherRC4(key, iv []byte, isRead bool) interface{} {
|
|
|
|
cipher, _ := rc4.NewCipher(key)
|
|
|
|
return cipher
|
|
|
|
}
|
|
|
|
|
2011-10-11 18:07:32 +01:00
|
|
|
func cipher3DES(key, iv []byte, isRead bool) interface{} {
|
|
|
|
block, _ := des.NewTripleDESCipher(key)
|
|
|
|
if isRead {
|
|
|
|
return cipher.NewCBCDecrypter(block, iv)
|
|
|
|
}
|
|
|
|
return cipher.NewCBCEncrypter(block, iv)
|
|
|
|
}
|
|
|
|
|
2010-12-15 16:49:55 +00:00
|
|
|
func cipherAES(key, iv []byte, isRead bool) interface{} {
|
|
|
|
block, _ := aes.NewCipher(key)
|
|
|
|
if isRead {
|
|
|
|
return cipher.NewCBCDecrypter(block, iv)
|
|
|
|
}
|
|
|
|
return cipher.NewCBCEncrypter(block, iv)
|
|
|
|
}
|
|
|
|
|
2011-09-14 20:32:19 +01:00
|
|
|
// macSHA1 returns a macFunction for the given protocol version.
|
|
|
|
func macSHA1(version uint16, key []byte) macFunction {
|
2013-06-05 01:02:22 +01:00
|
|
|
if version == VersionSSL30 {
|
2011-09-14 20:32:19 +01:00
|
|
|
mac := ssl30MAC{
|
|
|
|
h: sha1.New(),
|
|
|
|
key: make([]byte, len(key)),
|
|
|
|
}
|
|
|
|
copy(mac.key, key)
|
|
|
|
return mac
|
|
|
|
}
|
2015-12-23 02:03:44 +00:00
|
|
|
return tls10MAC{hmac.New(newConstantTimeHash(sha1.New), key)}
|
2011-09-14 20:32:19 +01:00
|
|
|
}
|
|
|
|
|
2016-08-18 22:49:01 +01:00
|
|
|
// macSHA256 returns a SHA-256 based MAC. These are only supported in TLS 1.2
|
|
|
|
// so the given version is ignored.
|
2016-08-18 00:45:47 +01:00
|
|
|
func macSHA256(version uint16, key []byte) macFunction {
|
|
|
|
return tls10MAC{hmac.New(sha256.New, key)}
|
|
|
|
}
|
|
|
|
|
2011-09-14 20:32:19 +01:00
|
|
|
type macFunction interface {
|
|
|
|
Size() int
|
2015-12-23 02:03:44 +00:00
|
|
|
MAC(digestBuf, seq, header, data, extra []byte) []byte
|
2011-09-14 20:32:19 +01:00
|
|
|
}
|
|
|
|
|
2013-08-29 22:18:59 +01:00
|
|
|
// fixedNonceAEAD wraps an AEAD and prefixes a fixed portion of the nonce to
|
|
|
|
// each call.
|
|
|
|
type fixedNonceAEAD struct {
|
|
|
|
// sealNonce and openNonce are buffers where the larger nonce will be
|
|
|
|
// constructed. Since a seal and open operation may be running
|
|
|
|
// concurrently, there is a separate buffer for each.
|
|
|
|
sealNonce, openNonce []byte
|
|
|
|
aead cipher.AEAD
|
|
|
|
}
|
|
|
|
|
|
|
|
func (f *fixedNonceAEAD) NonceSize() int { return 8 }
|
|
|
|
func (f *fixedNonceAEAD) Overhead() int { return f.aead.Overhead() }
|
|
|
|
|
|
|
|
func (f *fixedNonceAEAD) Seal(out, nonce, plaintext, additionalData []byte) []byte {
|
|
|
|
copy(f.sealNonce[len(f.sealNonce)-8:], nonce)
|
|
|
|
return f.aead.Seal(out, f.sealNonce, plaintext, additionalData)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (f *fixedNonceAEAD) Open(out, nonce, plaintext, additionalData []byte) ([]byte, error) {
|
|
|
|
copy(f.openNonce[len(f.openNonce)-8:], nonce)
|
|
|
|
return f.aead.Open(out, f.openNonce, plaintext, additionalData)
|
|
|
|
}
|
|
|
|
|
|
|
|
func aeadAESGCM(key, fixedNonce []byte) cipher.AEAD {
|
|
|
|
aes, err := aes.NewCipher(key)
|
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
aead, err := cipher.NewGCM(aes)
|
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
nonce1, nonce2 := make([]byte, 12), make([]byte, 12)
|
|
|
|
copy(nonce1, fixedNonce)
|
|
|
|
copy(nonce2, fixedNonce)
|
|
|
|
|
|
|
|
return &fixedNonceAEAD{nonce1, nonce2, aead}
|
|
|
|
}
|
|
|
|
|
2011-09-14 20:32:19 +01:00
|
|
|
// ssl30MAC implements the SSLv3 MAC function, as defined in
|
|
|
|
// www.mozilla.org/projects/security/pki/nss/ssl/draft302.txt section 5.2.3.1
|
|
|
|
type ssl30MAC struct {
|
|
|
|
h hash.Hash
|
|
|
|
key []byte
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s ssl30MAC) Size() int {
|
|
|
|
return s.h.Size()
|
|
|
|
}
|
|
|
|
|
|
|
|
var ssl30Pad1 = [48]byte{0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36}
|
|
|
|
|
|
|
|
var ssl30Pad2 = [48]byte{0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c}
|
|
|
|
|
2015-12-23 02:03:44 +00:00
|
|
|
// MAC does not offer constant timing guarantees for SSL v3.0, since it's deemed
|
|
|
|
// useless considering the similar, protocol-level POODLE vulnerability.
|
|
|
|
func (s ssl30MAC) MAC(digestBuf, seq, header, data, extra []byte) []byte {
|
2011-09-14 20:32:19 +01:00
|
|
|
padLength := 48
|
|
|
|
if s.h.Size() == 20 {
|
|
|
|
padLength = 40
|
|
|
|
}
|
|
|
|
|
|
|
|
s.h.Reset()
|
|
|
|
s.h.Write(s.key)
|
|
|
|
s.h.Write(ssl30Pad1[:padLength])
|
|
|
|
s.h.Write(seq)
|
2013-06-05 01:02:22 +01:00
|
|
|
s.h.Write(header[:1])
|
|
|
|
s.h.Write(header[3:5])
|
|
|
|
s.h.Write(data)
|
2011-12-06 23:25:14 +00:00
|
|
|
digestBuf = s.h.Sum(digestBuf[:0])
|
2011-09-14 20:32:19 +01:00
|
|
|
|
|
|
|
s.h.Reset()
|
|
|
|
s.h.Write(s.key)
|
|
|
|
s.h.Write(ssl30Pad2[:padLength])
|
2011-12-06 23:25:14 +00:00
|
|
|
s.h.Write(digestBuf)
|
|
|
|
return s.h.Sum(digestBuf[:0])
|
2011-09-14 20:32:19 +01:00
|
|
|
}
|
|
|
|
|
2015-12-23 02:03:44 +00:00
|
|
|
type constantTimeHash interface {
|
|
|
|
hash.Hash
|
|
|
|
ConstantTimeSum(b []byte) []byte
|
|
|
|
}
|
|
|
|
|
|
|
|
// cthWrapper wraps any hash.Hash that implements ConstantTimeSum, and replaces
|
|
|
|
// with that all calls to Sum. It's used to obtain a ConstantTimeSum-based HMAC.
|
|
|
|
type cthWrapper struct {
|
|
|
|
h constantTimeHash
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *cthWrapper) Size() int { return c.h.Size() }
|
|
|
|
func (c *cthWrapper) BlockSize() int { return c.h.BlockSize() }
|
|
|
|
func (c *cthWrapper) Reset() { c.h.Reset() }
|
|
|
|
func (c *cthWrapper) Write(p []byte) (int, error) { return c.h.Write(p) }
|
|
|
|
func (c *cthWrapper) Sum(b []byte) []byte { return c.h.ConstantTimeSum(b) }
|
|
|
|
|
|
|
|
func newConstantTimeHash(h func() hash.Hash) func() hash.Hash {
|
|
|
|
return func() hash.Hash {
|
|
|
|
return &cthWrapper{h().(constantTimeHash)}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-09-14 20:32:19 +01:00
|
|
|
// tls10MAC implements the TLS 1.0 MAC function. RFC 2246, section 6.2.3.
|
|
|
|
type tls10MAC struct {
|
|
|
|
h hash.Hash
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s tls10MAC) Size() int {
|
|
|
|
return s.h.Size()
|
|
|
|
}
|
|
|
|
|
2015-12-23 02:03:44 +00:00
|
|
|
// MAC is guaranteed to take constant time, as long as
|
|
|
|
// len(seq)+len(header)+len(data)+len(extra) is constant. extra is not fed into
|
|
|
|
// the MAC, but is only provided to make the timing profile constant.
|
|
|
|
func (s tls10MAC) MAC(digestBuf, seq, header, data, extra []byte) []byte {
|
2011-09-14 20:32:19 +01:00
|
|
|
s.h.Reset()
|
|
|
|
s.h.Write(seq)
|
2013-06-05 01:02:22 +01:00
|
|
|
s.h.Write(header)
|
|
|
|
s.h.Write(data)
|
2015-12-23 02:03:44 +00:00
|
|
|
res := s.h.Sum(digestBuf[:0])
|
|
|
|
if extra != nil {
|
|
|
|
s.h.Write(extra)
|
|
|
|
}
|
|
|
|
return res
|
2010-12-15 16:49:55 +00:00
|
|
|
}
|
|
|
|
|
2013-07-03 00:58:56 +01:00
|
|
|
func rsaKA(version uint16) keyAgreement {
|
2010-12-16 22:10:50 +00:00
|
|
|
return rsaKeyAgreement{}
|
|
|
|
}
|
|
|
|
|
2013-07-17 17:33:16 +01:00
|
|
|
func ecdheECDSAKA(version uint16) keyAgreement {
|
|
|
|
return &ecdheKeyAgreement{
|
|
|
|
sigType: signatureECDSA,
|
|
|
|
version: version,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-07-03 00:58:56 +01:00
|
|
|
func ecdheRSAKA(version uint16) keyAgreement {
|
2013-07-17 17:33:16 +01:00
|
|
|
return &ecdheKeyAgreement{
|
|
|
|
sigType: signatureRSA,
|
2013-07-03 00:58:56 +01:00
|
|
|
version: version,
|
|
|
|
}
|
2010-12-16 22:10:50 +00:00
|
|
|
}
|
|
|
|
|
2011-11-28 20:34:16 +00:00
|
|
|
// mutualCipherSuite returns a cipherSuite given a list of supported
|
2010-12-15 16:49:55 +00:00
|
|
|
// ciphersuites and the id requested by the peer.
|
2011-11-28 20:34:16 +00:00
|
|
|
func mutualCipherSuite(have []uint16, want uint16) *cipherSuite {
|
2010-12-15 16:49:55 +00:00
|
|
|
for _, id := range have {
|
2010-12-15 18:58:57 +00:00
|
|
|
if id == want {
|
2011-11-28 20:34:16 +00:00
|
|
|
for _, suite := range cipherSuites {
|
|
|
|
if suite.id == want {
|
|
|
|
return suite
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return nil
|
2010-12-15 16:49:55 +00:00
|
|
|
}
|
|
|
|
}
|
2011-11-28 20:34:16 +00:00
|
|
|
return nil
|
2010-12-15 16:49:55 +00:00
|
|
|
}
|
|
|
|
|
2016-03-10 23:49:30 +00:00
|
|
|
// A list of cipher suite IDs that are, or have been, implemented by this
|
|
|
|
// package.
|
|
|
|
//
|
|
|
|
// Taken from http://www.iana.org/assignments/tls-parameters/tls-parameters.xml
|
2010-12-15 16:49:55 +00:00
|
|
|
const (
|
2013-08-29 22:18:59 +01:00
|
|
|
TLS_RSA_WITH_RC4_128_SHA uint16 = 0x0005
|
|
|
|
TLS_RSA_WITH_3DES_EDE_CBC_SHA uint16 = 0x000a
|
|
|
|
TLS_RSA_WITH_AES_128_CBC_SHA uint16 = 0x002f
|
|
|
|
TLS_RSA_WITH_AES_256_CBC_SHA uint16 = 0x0035
|
2016-08-18 00:45:47 +01:00
|
|
|
TLS_RSA_WITH_AES_128_CBC_SHA256 uint16 = 0x003c
|
2015-11-15 00:53:03 +00:00
|
|
|
TLS_RSA_WITH_AES_128_GCM_SHA256 uint16 = 0x009c
|
|
|
|
TLS_RSA_WITH_AES_256_GCM_SHA384 uint16 = 0x009d
|
2013-08-29 22:18:59 +01:00
|
|
|
TLS_ECDHE_ECDSA_WITH_RC4_128_SHA uint16 = 0xc007
|
|
|
|
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA uint16 = 0xc009
|
|
|
|
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA uint16 = 0xc00a
|
|
|
|
TLS_ECDHE_RSA_WITH_RC4_128_SHA uint16 = 0xc011
|
|
|
|
TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA uint16 = 0xc012
|
|
|
|
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA uint16 = 0xc013
|
|
|
|
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA uint16 = 0xc014
|
2016-08-18 00:45:47 +01:00
|
|
|
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 uint16 = 0xc023
|
|
|
|
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 uint16 = 0xc027
|
2013-08-29 22:18:59 +01:00
|
|
|
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 uint16 = 0xc02f
|
|
|
|
TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 uint16 = 0xc02b
|
2015-02-04 00:15:18 +00:00
|
|
|
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 uint16 = 0xc030
|
|
|
|
TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 uint16 = 0xc02c
|
2014-10-16 01:54:04 +01:00
|
|
|
|
|
|
|
// TLS_FALLBACK_SCSV isn't a standard cipher suite but an indicator
|
|
|
|
// that the client is doing version fallback. See
|
2016-02-15 16:56:18 +00:00
|
|
|
// https://tools.ietf.org/html/rfc7507.
|
2014-10-16 01:54:04 +01:00
|
|
|
TLS_FALLBACK_SCSV uint16 = 0x5600
|
2010-12-15 16:49:55 +00:00
|
|
|
)
|