Commit graph

401 commits

Author SHA1 Message Date
Filippo Valsorda
5b79a7c982 crypto/tls: implement TLS 1.3 middlebox compatibility mode
Looks like the introduction of CCS records in the client second flight
gave time to s_server to send NewSessionTicket messages in between the
client application data and close_notify. There seems to be no way of
turning NewSessionTicket messages off, neither by not sending a
psk_key_exchange_modes extension, nor by command line flag.

Interleaving the client write like that tickled an issue akin to #18701:
on Windows, the client reaches Close() before the last record is drained
from the send buffer, the kernel notices and resets the connection,
cutting short the last flow. There is no good way of synchronizing this,
so we sleep for a RTT before calling close, like in CL 75210. Sigh.

Updates #9671

Change-Id: I44dc1cca17b373695b5a18c2741f218af2990bd1
Reviewed-on: https://go-review.googlesource.com/c/147419
Run-TryBot: Filippo Valsorda <filippo@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Adam Langley <agl@golang.org>
2018-11-12 20:43:06 +00:00
Filippo Valsorda
e04a8ac694 crypto/tls: implement TLS 1.3 KeyUpdate messages
Since TLS 1.3 delivers handshake messages (including KeyUpdate) after
the handshake, the want argument to readRecord had became almost
pointless: it only meant something when set to recordTypeChangeCipherSpec.
Replaced it with a bool to reflect that, and added two shorthands to
avoid anonymous bools in calls.

Took the occasion to simplify and formalize the invariants of readRecord.

The maxConsecutiveEmptyRecords loop became useless when readRecord
started retrying on any non-advancing record in CL 145297.

Replaced panics with errors, because failure is better than undefined
behavior, but contained failure is better than a DoS vulnerability. For
example, I suspect the panic at the top of readRecord was reachable from
handleRenegotiation, which calls readHandshake with handshakeComplete
false. Thankfully it was not a panic in 1.11, and it's allowed now.

Removed Client-TLSv13-RenegotiationRejected because OpenSSL isn't
actually willing to ask for renegotiation over TLS 1.3, the expected
error was due to NewSessionTicket messages, which didn't break the rest
of the tests because they stop too soon.

Updates #9671

Change-Id: I297a81bde5c8020a962a92891b70d6d70b90f5e3
Reviewed-on: https://go-review.googlesource.com/c/147418
Run-TryBot: Filippo Valsorda <filippo@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Adam Langley <agl@golang.org>
2018-11-12 20:42:36 +00:00
Filippo Valsorda
f513a10f59 crypto/tls: implement TLS 1.3 KeyLogWriter support
Also, add support for the SSLKEYLOGFILE environment variable to the
tests, to simplify debugging of unexpected failures.

Updates #9671

Change-Id: I20a34a5824f083da93097b793d51e796d6eb302b
Reviewed-on: https://go-review.googlesource.com/c/147417
Run-TryBot: Filippo Valsorda <filippo@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Adam Langley <agl@golang.org>
2018-11-12 20:42:20 +00:00
Filippo Valsorda
b85722092b crypto/tls: remove a forgotten note to future self
Now, this is embarrassing. While preparing CL 142818, I noticed a
possible vulnerability in the existing code which I was rewriting. I
took a note to go back and assess if it was indeed an issue, and in case
start the security release process. The note unintentionally slipped
into the commit. Fortunately, there was no vulnerability.

What caught my eye was that I had fixed the calculation of the minimum
encrypted payload length from

    roundUp(explicitIVLen+macSize+1, blockSize)

to (using the same variable names)

    explicitIVLen + roundUp(macSize+1, blockSize)

The explicit nonce sits outside of the encrypted payload, so it should
not be part of the value rounded up to the CBC block size.

You can see that for some values of the above, the old result could be
lower than the correct value. An unexpectedly short payload might cause
a panic during decryption (a DoS vulnerability) or even more serious
issues due to the constant time code that follows it (see for example
Yet Another Padding Oracle in OpenSSL CBC Ciphersuites [1]).

In practice, explicitIVLen is either zero or equal to blockSize, so it
does not change the amount of rounding up necessary and the two
formulations happen to be identical. Nothing to see here.

It looked more suspicious than it is in part due to the fact that the
explicitIVLen definition moved farther into hc.explicitNonceLen() and
changed name from IV (which suggests a block length) to nonce (which
doesn't necessarily). But anyway it was never meant to surface or be
noted, except it slipped, so here we are for a boring explanation.

[1] https://blog.cloudflare.com/yet-another-padding-oracle-in-openssl-cbc-ciphersuites/

Change-Id: I365560dfe006513200fa877551ce7afec9115fdf
Reviewed-on: https://go-review.googlesource.com/c/147637
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2018-11-08 06:13:12 +00:00
Filippo Valsorda
376ff45dc1 crypto/tls: implement TLS 1.3 server handshake (base)
Implement a basic TLS 1.3 server handshake, only enabled if explicitly
requested with MaxVersion.

This CL intentionally leaves for future CLs:
  - PSK modes and resumption
  - client authentication
  - compatibility mode ChangeCipherSpecs
  - early data skipping
  - post-handshake messages
  - downgrade protection
  - KeyLogWriter support
  - TLS_FALLBACK_SCSV processing

It also leaves a few areas up for a wider refactor (maybe in Go 1.13):
  - the certificate selection logic can be significantly improved,
    including supporting and surfacing signature_algorithms_cert, but
    this isn't new in TLS 1.3 (see comment in processClientHello)
  - handshake_server_tls13.go can be dried up and broken into more
    meaningful, smaller functions, but it felt premature to do before
    PSK and client auth support
  - the monstrous ClientHello equality check in doHelloRetryRequest can
    get both cleaner and more complete with collaboration from the
    parsing layer, which can come at the same time as extension
    duplicates detection

Updates #9671

Change-Id: Id9db2b6ecc2eea21bf9b59b6d1d9c84a7435151c
Reviewed-on: https://go-review.googlesource.com/c/147017
Run-TryBot: Filippo Valsorda <filippo@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Adam Langley <agl@golang.org>
2018-11-02 22:07:43 +00:00
Filippo Valsorda
2c3ff7ba06 crypto/tls: implement TLS 1.3 client handshake (base)
Implement a basic TLS 1.3 client handshake, only enabled if explicitly
requested with MaxVersion.

This CL intentionally leaves for future CLs:
  - PSK modes and resumption
  - client authentication
  - post-handshake messages
  - downgrade protection
  - KeyLogWriter support

Updates #9671

Change-Id: Ieb6130fb6f25aea4f0d39e3a2448dfc942e1de7a
Reviewed-on: https://go-review.googlesource.com/c/146559
Run-TryBot: Filippo Valsorda <filippo@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Adam Langley <agl@golang.org>
2018-11-02 22:07:02 +00:00
Filippo Valsorda
ed74f7823e crypto/tls: advertise and accept rsa_pss_rsae signature algorithms
crypto/x509 already supports PSS signatures (with rsaEncryption OID),
and crypto/tls support was added in CL 79736. Advertise support for the
algorithms and accept them as a peer.

Note that this is about PSS signatures from regular RSA public keys.
RSA-PSS only public keys (with RSASSA-PSS OID) are supported in neither
crypto/tls nor crypto/x509. See RFC 8446, Section 4.2.3.

testdata/Server-TLSv12-ClientAuthRequested* got modified because the
CertificateRequest carries the supported signature algorithms.

The net/smtp tests changed because 512 bits keys are too small for PSS.

Based on Peter Wu's CL 79738, who did all the actual work in CL 79736.

Updates #9671

Change-Id: I4a31e9c6e152ff4c50a5c8a274edd610d5fff231
Reviewed-on: https://go-review.googlesource.com/c/146258
Run-TryBot: Filippo Valsorda <filippo@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Adam Langley <agl@golang.org>
2018-11-02 22:05:52 +00:00
Filippo Valsorda
6d1d147e90 crypto/tls: implement TLS 1.3 version negotiation
RFC 8446 recommends using the supported_versions extension to negotiate
lower versions as well, so begin by implementing it to negotiate the
currently supported versions.

Note that pickTLSVersion was incorrectly negotiating the ServerHello
version down on the client. If the server had illegally sent a version
higher than the ClientHello version, the client would have just
downgraded it, hopefully failing later in the handshake.

In TestGetConfigForClient, we were hitting the record version check
because the server would select TLS 1.1, the handshake would fail on the
client which required TLS 1.2, which would then send a TLS 1.0 record
header on its fatal alert (not having negotiated a version), while the
server would expect a TLS 1.1 header at that point. Now, the client gets
to communicate the minimum version through the extension and the
handshake fails on the server.

Updates #9671

Change-Id: Ie33c7124c0c769f62e10baad51cbed745c424e5b
Reviewed-on: https://go-review.googlesource.com/c/146217
Run-TryBot: Filippo Valsorda <filippo@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Adam Langley <agl@golang.org>
2018-11-02 22:05:06 +00:00
Filippo Valsorda
d4e9432552 crypto/tls: implement TLS 1.3 version-specific messages
Note that there is significant code duplication due to extensions with
the same format appearing in different messages in TLS 1.3. This will be
cleaned up in a future refactor once CL 145317 is merged.

Enforcing the presence/absence of each extension in each message is left
to the upper layer, based on both protocol version and extensions
advertised in CH and CR. Duplicated extensions and unknown extensions in
SH, EE, HRR, and CT will be tightened up in a future CL.

The TLS 1.2 CertificateStatus message was restricted to accepting only
type OCSP as any other type (none of which are specified so far) would
have to be negotiated.

Updates #9671

Change-Id: I7c42394c5cc0af01faa84b9b9f25fdc6e7cfbb9e
Reviewed-on: https://go-review.googlesource.com/c/145477
Reviewed-by: Adam Langley <agl@golang.org>
2018-11-02 22:04:51 +00:00
Filippo Valsorda
3fdae13d6a crypto/tls: implement TLS 1.3 cryptographic computations
Vendors golang.org/x/crypto/hkdf at e84da0312774c21d64ee2317962ef669b27ffb41

Updates #9671

Change-Id: I2610c4a66756e2a6f21f9823dcbe39edd9c9ea21
Reviewed-on: https://go-review.googlesource.com/c/145298
Reviewed-by: Adam Langley <agl@golang.org>
2018-11-02 21:54:52 +00:00
Filippo Valsorda
34eda04c4f crypto/tls: implement TLS 1.3 record layer and cipher suites
Updates #9671

Change-Id: I1ea7b724975c0841d01f4536eebb23956b30d5ea
Reviewed-on: https://go-review.googlesource.com/c/145297
Reviewed-by: Adam Langley <agl@golang.org>
2018-11-02 21:54:38 +00:00
Filippo Valsorda
4900f4cb3a crypto/tls: implement TLS 1.3 extensions for ClientHello and ServerHello
Updates #9671

Change-Id: Ia68224aca866dc3c98af1fccbe56bfb3f22da9f6
Reviewed-on: https://go-review.googlesource.com/c/144578
Run-TryBot: Filippo Valsorda <filippo@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Adam Langley <agl@golang.org>
2018-11-02 21:54:22 +00:00
Darien Raymond
9ba50a7a9f crypto/tls: cache Leaf certificate during BuildNameToCertificate
I am working on a TLS server program, which issues new TLS certificates
on demand. The new certificates will be added into tls.Config.Certificates.
BuildNameToCertificate will be called to refresh the name table afterwards.
This change will reduce some workload on existing certificates.

Note that you can’t modify the Certificates field (or call BuildNameToCertificate)
on a Config in use by a Server. You can however modify an unused Config that gets
cloned in GetConfigForClient with appropriate locking.

Change-Id: I7bdb7d23fc5d68df83c73f3bfa3ba9181d38fbde
GitHub-Last-Rev: c3788f4116be47f2fdb777935c421e7dd694f5c8
GitHub-Pull-Request: golang/go#24920
Reviewed-on: https://go-review.googlesource.com/c/107627
Reviewed-by: Filippo Valsorda <filippo@golang.org>
2018-10-31 14:39:11 +00:00
Pontus Leitzler
5aa5e4cef7 crypto/tls: clarify documentation on tls.Config.NextProtos
This change will aid users to make less mistakes where you, for example, define both HTTP/1.1 and H2, but in the wrong order.

    package main

    import (
        "crypto/tls"
        "net"
    )

    func main() {
        srv := &http.Server{
            TLSConfig: &tls.Config{
                NextProtos: []string{"http/1.1", "h2"},
            },
        }
        srv.ListenAndServeTLS("server.crt", "server.key")
    }

When using major browsers or curl, they will never be served H2 since they also support HTTP/1.0 and the list is processed in order.

Change-Id: Id14098b5e48f624ca308137917874d475c2f22a0
GitHub-Last-Rev: f3594a6411bf7dde71c850f3e85a2b5a21974129
GitHub-Pull-Request: golang/go#28367
Reviewed-on: https://go-review.googlesource.com/c/144387
Reviewed-by: Filippo Valsorda <filippo@golang.org>
2018-10-30 15:07:42 +00:00
Tim Cooper
c9ff1b96f3 crypto/tls: remove unneeded calls to bytes.NewReader
Updates #28269

Change-Id: Iae765f85e6ae49f4b581161ed489b2f5ee27cdba
Reviewed-on: https://go-review.googlesource.com/c/145737
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2018-10-30 01:43:09 +00:00
Filippo Valsorda
8d011ce74c crypto/tls: rewrite some messages with golang.org/x/crypto/cryptobyte
As a first round, rewrite those handshake message types which can be
reused in TLS 1.3 with golang.org/x/crypto/cryptobyte. All other types
changed significantly in TLS 1.3 and will require separate
implementations. They will be ported to cryptobyte in a later CL.

The only semantic changes should be enforcing the random length on the
marshaling side, enforcing a couple more "must not be empty" on the
unmarshaling side, and checking the rest of the SNI list even if we only
take the first.

Change-Id: Idd2ced60c558fafcf02ee489195b6f3b4735fe22
Reviewed-on: https://go-review.googlesource.com/c/144115
Run-TryBot: Filippo Valsorda <filippo@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Adam Langley <agl@golang.org>
2018-10-29 17:05:55 +00:00
Filippo Valsorda
d2f8d62861 crypto/tls: bump test timeouts from 1s to 1m for slow builders
The arm5 and mips builders are can't-send-a-packet-to-localhost-in-1s
slow apparently. 1m is less useful, but still better than an obscure
test timeout panic.

Fixes #28405

Change-Id: I2feeae6ea1b095114caccaab4f6709f405faebad
Reviewed-on: https://go-review.googlesource.com/c/145037
Run-TryBot: Filippo Valsorda <filippo@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2018-10-27 22:12:17 +00:00
Filippo Valsorda
e58787c05a crypto/tls: replace custom equal implementations with reflect.DeepEqual
The equal methods were only there for testing, and I remember regularly
getting them wrong while developing tls-tris. Replace them with simple
reflect.DeepEqual calls.

The only special thing that equal() would do is ignore the difference
between a nil and a zero-length slice. Fixed the Generate methods so
that they create the same value that unmarshal will decode. The
difference is not important: it wasn't tested, all checks are
"len(slice) > 0", and all cases in which presence matters are
accompanied by a boolean.

Change-Id: Iaabf56ea17c2406b5107c808c32f6c85b611aaa8
Reviewed-on: https://go-review.googlesource.com/c/144114
Run-TryBot: Filippo Valsorda <filippo@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Adam Langley <agl@golang.org>
2018-10-25 19:07:36 +00:00
Filippo Valsorda
721ba6fc20 crypto/tls: add timeouts to recorded tests
If something causes the recorded tests to deviate from the expected
flows, they might wait forever for data that is not coming. Add a short
timeout, after which a useful error message is shown.

Change-Id: Ib11ccc0e17dcb8b2180493556017275678abbb08
Reviewed-on: https://go-review.googlesource.com/c/144116
Run-TryBot: Filippo Valsorda <filippo@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Adam Langley <agl@golang.org>
2018-10-25 19:02:40 +00:00
Brad Fitzpatrick
9986f57938 crypto/tls, net/http: reject HTTP requests to HTTPS server
This adds a crypto/tls.RecordHeaderError.Conn field containing the TLS
underlying net.Conn for non-TLS handshake errors, and then uses it in
the net/http Server to return plaintext HTTP 400 errors when a client
mistakenly sends a plaintext HTTP request to an HTTPS server. This is the
same behavior as Apache.

Also in crypto/tls: swap two error paths to not use a value before
it's valid, and don't send a alert record when a handshake contains a
bogus TLS record (a TLS record in response won't help a non-TLS
client).

Fixes #23689

Change-Id: Ife774b1e3886beb66f25ae4587c62123ccefe847
Reviewed-on: https://go-review.googlesource.com/c/143177
Reviewed-by: Filippo Valsorda <filippo@golang.org>
2018-10-24 22:49:50 +00:00
golint fixer
0e6cb300a3 Fix golint import path 2018-10-24 14:51:42 -06:00
Filippo Valsorda
5d617aac88 crypto/tls: replace custom *block with standard buffers
The crypto/tls record layer used a custom buffer implementation with its
own semantics, freelist, and offset management. Replace it all with
per-task bytes.Buffer, bytes.Reader and byte slices, along with a
refactor of all the encrypt and decrypt code.

The main quirk of *block was to do a best-effort read past the record
boundary, so that if a closeNotify was waiting it would be peeked and
surfaced along with the last Read. Address that with atLeastReader and
ReadFrom to avoid a useless copy (instead of a LimitReader or CopyN).

There was also an optimization to split blocks along record boundary
lines without having to copy in and out the data. Replicate that by
aliasing c.input into consumed c.rawInput (after an in-place decrypt
operation). This is safe because c.rawInput is not used until c.input is
drained.

The benchmarks are noisy but look like an improvement across the board,
which is a nice side effect :)

name                                       old time/op   new time/op   delta
HandshakeServer/RSA-8                        817µs ± 2%    797µs ± 2%  -2.52%  (p=0.000 n=10+9)
HandshakeServer/ECDHE-P256-RSA-8             984µs ±11%    897µs ± 0%  -8.89%  (p=0.000 n=10+9)
HandshakeServer/ECDHE-P256-ECDSA-P256-8      206µs ±10%    199µs ± 3%    ~     (p=0.113 n=10+9)
HandshakeServer/ECDHE-X25519-ECDSA-P256-8    204µs ± 3%    202µs ± 1%  -1.06%  (p=0.013 n=10+9)
HandshakeServer/ECDHE-P521-ECDSA-P521-8     15.5ms ± 0%   15.6ms ± 1%    ~     (p=0.095 n=9+10)
Throughput/MaxPacket/1MB-8                  5.35ms ±19%   5.39ms ±36%    ~     (p=1.000 n=9+10)
Throughput/MaxPacket/2MB-8                  9.20ms ±15%   8.30ms ± 8%  -9.79%  (p=0.035 n=10+9)
Throughput/MaxPacket/4MB-8                  13.8ms ± 7%   13.6ms ± 8%    ~     (p=0.315 n=10+10)
Throughput/MaxPacket/8MB-8                  25.1ms ± 3%   23.2ms ± 2%  -7.66%  (p=0.000 n=10+9)
Throughput/MaxPacket/16MB-8                 46.9ms ± 1%   43.0ms ± 3%  -8.29%  (p=0.000 n=9+10)
Throughput/MaxPacket/32MB-8                 88.9ms ± 2%   82.3ms ± 2%  -7.40%  (p=0.000 n=9+9)
Throughput/MaxPacket/64MB-8                  175ms ± 2%    164ms ± 4%  -6.18%  (p=0.000 n=10+10)
Throughput/DynamicPacket/1MB-8              5.79ms ±26%   5.82ms ±22%    ~     (p=0.912 n=10+10)
Throughput/DynamicPacket/2MB-8              9.23ms ±14%   9.50ms ±23%    ~     (p=0.971 n=10+10)
Throughput/DynamicPacket/4MB-8              14.5ms ±11%   13.8ms ± 6%  -4.66%  (p=0.019 n=10+10)
Throughput/DynamicPacket/8MB-8              25.6ms ± 4%   23.5ms ± 3%  -8.33%  (p=0.000 n=10+10)
Throughput/DynamicPacket/16MB-8             47.3ms ± 3%   44.6ms ± 7%  -5.65%  (p=0.000 n=10+10)
Throughput/DynamicPacket/32MB-8             91.9ms ±14%   85.0ms ± 4%  -7.55%  (p=0.000 n=10+10)
Throughput/DynamicPacket/64MB-8              177ms ± 2%    168ms ± 4%  -4.97%  (p=0.000 n=8+10)
Latency/MaxPacket/200kbps-8                  694ms ± 0%    694ms ± 0%    ~     (p=0.315 n=10+9)
Latency/MaxPacket/500kbps-8                  279ms ± 0%    279ms ± 0%    ~     (p=0.447 n=9+10)
Latency/MaxPacket/1000kbps-8                 140ms ± 0%    140ms ± 0%    ~     (p=0.661 n=9+10)
Latency/MaxPacket/2000kbps-8                71.1ms ± 0%   71.1ms ± 0%  +0.05%  (p=0.019 n=9+9)
Latency/MaxPacket/5000kbps-8                30.4ms ± 7%   30.5ms ± 4%    ~     (p=0.720 n=9+10)
Latency/DynamicPacket/200kbps-8              134ms ± 0%    134ms ± 0%    ~     (p=0.075 n=10+10)
Latency/DynamicPacket/500kbps-8             54.8ms ± 0%   54.8ms ± 0%    ~     (p=0.631 n=10+10)
Latency/DynamicPacket/1000kbps-8            28.5ms ± 0%   28.5ms ± 0%    ~     (p=1.000 n=8+8)
Latency/DynamicPacket/2000kbps-8            15.7ms ±12%   16.1ms ± 0%    ~     (p=0.109 n=10+7)
Latency/DynamicPacket/5000kbps-8            8.20ms ±26%   8.17ms ±13%    ~     (p=1.000 n=9+9)

name                                       old speed     new speed     delta
Throughput/MaxPacket/1MB-8                 193MB/s ±14%  202MB/s ±30%    ~     (p=0.897 n=8+10)
Throughput/MaxPacket/2MB-8                 230MB/s ±14%  249MB/s ±17%    ~     (p=0.089 n=10+10)
Throughput/MaxPacket/4MB-8                 304MB/s ± 6%  309MB/s ± 7%    ~     (p=0.315 n=10+10)
Throughput/MaxPacket/8MB-8                 334MB/s ± 3%  362MB/s ± 2%  +8.29%  (p=0.000 n=10+9)
Throughput/MaxPacket/16MB-8                358MB/s ± 1%  390MB/s ± 3%  +9.08%  (p=0.000 n=9+10)
Throughput/MaxPacket/32MB-8                378MB/s ± 2%  408MB/s ± 2%  +8.00%  (p=0.000 n=9+9)
Throughput/MaxPacket/64MB-8                384MB/s ± 2%  410MB/s ± 4%  +6.61%  (p=0.000 n=10+10)
Throughput/DynamicPacket/1MB-8             178MB/s ±24%  182MB/s ±24%    ~     (p=0.604 n=9+10)
Throughput/DynamicPacket/2MB-8             228MB/s ±13%  225MB/s ±20%    ~     (p=0.971 n=10+10)
Throughput/DynamicPacket/4MB-8             291MB/s ±10%  305MB/s ± 6%  +4.83%  (p=0.019 n=10+10)
Throughput/DynamicPacket/8MB-8             327MB/s ± 4%  357MB/s ± 3%  +9.08%  (p=0.000 n=10+10)
Throughput/DynamicPacket/16MB-8            355MB/s ± 3%  376MB/s ± 6%  +6.07%  (p=0.000 n=10+10)
Throughput/DynamicPacket/32MB-8            366MB/s ±12%  395MB/s ± 4%  +7.91%  (p=0.000 n=10+10)
Throughput/DynamicPacket/64MB-8            380MB/s ± 2%  400MB/s ± 4%  +5.26%  (p=0.000 n=8+10)

Note that this reduced the buffer for the first read from 1024 to 5+512,
so it triggered the issue described at #24198 when using a synchronous
net.Pipe: the first server flight was not being consumed entirely by the
first read anymore, causing a deadlock as both the client and the server
were trying to send (the client a reply to the ServerHello, the server
the rest of the buffer). Fixed by rebasing on top of CL 142817.

Change-Id: Ie31b0a572b2ad37878469877798d5c6a5276f931
Reviewed-on: https://go-review.googlesource.com/c/142818
Run-TryBot: Filippo Valsorda <filippo@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Adam Langley <agl@golang.org>
2018-10-24 10:03:23 +00:00
Filippo Valsorda
1b72cce3de crypto/tls: replace net.Pipe in tests with real TCP connections
crypto/tls is meant to work over network connections with buffering, not
synchronous connections, as explained in #24198. Tests based on net.Pipe
are unrealistic as reads and writes are matched one to one. Such tests
worked just thanks to the implementation details of the tls.Conn
internal buffering, and would break if for example the flush of the
first flight of the server was not entirely assimilated by the client
rawInput buffer before the client attempted to reply to the ServerHello.

Note that this might run into the Darwin network issues at #25696.

Fixed a few test races that were either hidden or synchronized by the
use of the in-memory net.Pipe.

Also, this gets us slightly more realistic benchmarks, reflecting some
syscall cost of Read and Write operations.

Change-Id: I5a597b3d7a81b8ccc776030cc837133412bf50f8
Reviewed-on: https://go-review.googlesource.com/c/142817
Run-TryBot: Filippo Valsorda <filippo@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2018-10-19 12:43:30 +00:00
Filippo Valsorda
db3edf68fa crypto/tls,crypto/x509: normalize RFC references
Use the format "RFC XXXX, Section X.X" (or "Appendix Y.X") as it fits
more properly in prose than a link, is more future-proof, and as there
are multiple ways to render an RFC. Capital "S" to follow the quoting
standard of RFCs themselves.

Applied the new goimports grouping to all files in those packages, too.

Change-Id: I01267bb3a3b02664f8f822e97b129075bb14d404
Reviewed-on: https://go-review.googlesource.com/c/141918
Reviewed-by: Dmitri Shuralyov <dmitshur@golang.org>
2018-10-17 03:58:03 +00:00
Marten Seemann
2800e0ffca crypto/tls: fix ServerHello SCT test
According to https://tools.ietf.org/html/rfc6962#section-3.3, the SCT
must be at least one byte long. The parsing code correctly checks for
this condition, but rarely the test does generate an empty SCT.

Change-Id: If36a34985b4470a5a9f96affc159195c04f6bfad
Reviewed-on: https://go-review.googlesource.com/c/129755
Reviewed-by: Filippo Valsorda <filippo@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2018-10-09 04:45:54 +00:00
Eric Wustrow
ca9872fd5f
Credit Jigsaw 2018-10-08 11:35:54 -06:00
Filippo Valsorda
0a9fc9c88a crypto/tls: make ConnectionState.ExportKeyingMaterial a method
The unexported field is hidden from reflect based marshalers, which
would break otherwise. Also, make it return an error, as there are
multiple reasons it might fail.

Fixes #27125

Change-Id: I92adade2fe456103d2d5c0315629ca0256953764
Reviewed-on: https://go-review.googlesource.com/130535
Run-TryBot: Filippo Valsorda <filippo@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2018-08-22 03:48:56 +00:00
Sergey Frolov
db1b65d230 Add Roller: Dialer that cycles thru ClientHellos 2018-07-31 12:20:07 -04:00
Sergey Frolov
4c28dcf6db Clarify ApplyPreset description 2018-07-30 14:29:21 -04:00
Sergey Frolov
e7ad106121 Doc update: use separate custom ClientHelloSpecs 2018-07-30 14:29:21 -04:00
Sergey Frolov
2551de140c Fix statefulness 2018-07-30 14:29:21 -04:00
Minaev Mike
6d965709ab crypto/tls: fix deadlock when Read and Close called concurrently
The existing implementation of TLS connection has a deadlock. It occurs
when client connects to TLS server and doesn't send data for
handshake, so server calls Close on this connection. This is because
server reads data under locked mutex, while Close method tries to
lock the same mutex.

Fixes #23518

Change-Id: I4fb0a2a770f3d911036bfd9a7da7cc41c1b27e19
Reviewed-on: https://go-review.googlesource.com/90155
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Filippo Valsorda <filippo@golang.org>
2018-07-25 23:53:54 +00:00
sergeyfrolov
03d875d854
README: add iOS 11.1 2018-07-24 10:45:51 -04:00
Sergey Frolov
4930c22447 Add iOS 11 fingerprint 2018-07-23 18:24:04 -04:00
Vlad Krasnov
6823718107 crypto/aes: implement AES-GCM AEAD for arm64
Use the dedicated AES* and PMULL* instructions to accelerate AES-GCM

name              old time/op    new time/op      delta
AESGCMSeal1K-46     12.1µs ± 0%       0.9µs ± 0%    -92.66%  (p=0.000 n=9+10)
AESGCMOpen1K-46     12.1µs ± 0%       0.9µs ± 0%    -92.43%  (p=0.000 n=10+10)
AESGCMSign8K-46     58.6µs ± 0%       2.1µs ± 0%    -96.41%  (p=0.000 n=9+8)
AESGCMSeal8K-46     92.8µs ± 0%       5.7µs ± 0%    -93.86%  (p=0.000 n=9+9)
AESGCMOpen8K-46     92.9µs ± 0%       5.7µs ± 0%    -93.84%  (p=0.000 n=8+9)

name              old speed      new speed        delta
AESGCMSeal1K-46   84.7MB/s ± 0%  1153.4MB/s ± 0%  +1262.21%  (p=0.000 n=9+10)
AESGCMOpen1K-46   84.4MB/s ± 0%  1115.2MB/s ± 0%  +1220.53%  (p=0.000 n=10+10)
AESGCMSign8K-46    140MB/s ± 0%    3894MB/s ± 0%  +2687.50%  (p=0.000 n=9+10)
AESGCMSeal8K-46   88.2MB/s ± 0%  1437.5MB/s ± 0%  +1529.30%  (p=0.000 n=9+9)
AESGCMOpen8K-46   88.2MB/s ± 0%  1430.5MB/s ± 0%  +1522.01%  (p=0.000 n=8+9)

This change mirrors the current amd64 implementation, and provides optimal performance
on a range of arm64 processors including Centriq 2400 and Apple A12. By and large it is
implicitly tested by the robustness of the already existing amd64 implementation.

The implementation interleaves GHASH with CTR mode to achieve the highest possible
throughput, it also aggregates GHASH with a factor of 8, to decrease the cost of the
reduction step.

Even thought there is a significant amount of assembly, the code reuses the go
code for the amd64 implementation, so there is little additional go code.

Since AES-GCM is critical for performance of all web servers, this change is
required to level the playfield for arm64 CPUs, where amd64 currently enjoys an
unfair advantage.

Ideally both amd64 and arm64 codepaths could be replaced by hypothetical AES and
CLMUL intrinsics, with a few additional vector instructions.

Fixes #18498
Fixes #19840

Change-Id: Icc57b868cd1f67ac695c1ac163a8e215f74c7910
Reviewed-on: https://go-review.googlesource.com/107298
Run-TryBot: Vlad Krasnov <vlad@cloudflare.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2018-07-20 03:30:04 +00:00
Peter Wu
0524876ddb crypto/tls: add RSASSA-PSS support for handshake messages
This adds support for RSASSA-PSS signatures in handshake messages as
required by TLS 1.3. Even if TLS 1.2 is negotiated, it must support PSS
when advertised in the Client Hello (this will be done later as the
testdata will change).

Updates #9671

Change-Id: I8006b92e017453ae408c153233ce5ccef99b5c3f
Reviewed-on: https://go-review.googlesource.com/79736
Reviewed-by: Filippo Valsorda <filippo@golang.org>
2018-06-27 23:08:06 +00:00
Sergey Frolov
e0edd7863b Rename FakeGREASEExtension -> UtlsGREASEExtension 2018-06-27 14:19:30 -04:00
Sergey Frolov
47f47cf66d Update EMS comment: implemented due to popularity 2018-06-21 13:55:02 -04:00
Sergey Frolov
8dcadf2736 Bump min Go version to 1.9, gofmt 2018-06-21 13:55:02 -04:00
Sergey Frolov
112951f6d7 Refactor: enable flexible external configuration 2018-06-21 13:55:02 -04:00
Sergey Frolov
690d770374 Standard internal logic to detect hardware crypto
We can't simply link to system internal package, as it is prohibited by
Golang. Let's copy-paste instead.
2018-06-21 11:53:24 -04:00
Peter Wu
611a58ad27 crypto/tls: consolidate signatures handling in SKE and CV
ServerKeyExchange and CertificateVerify can share the same logic for
picking a signature algorithm (based on the certificate public key and
advertised algorithms), selecting a hash algorithm (depending on TLS
version) and signature verification.

Refactor the code to achieve code reuse, have common error checking
(especially for intersecting supported signature algorithms) and to
prepare for addition of new signature algorithms. Code should be easier
to read since version-dependent logic is concentrated at one place.

Change-Id: I978dec3815d28e33c3cfbc85f0c704b1894c25a3
Reviewed-on: https://go-review.googlesource.com/79735
Reviewed-by: Filippo Valsorda <filippo@golang.org>
Run-TryBot: Filippo Valsorda <filippo@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2018-06-20 17:15:50 +00:00
sergeyfrolov
193d4b28e8
Merge pull request #5 from refraction-networking/merge-upstream
Merge upstream crypto/tls
2018-06-19 19:02:06 -04:00
Sergey Frolov
9656990081 Merge branch 'golang-tls-upstream', remove Android
I tested all fingerprints and confirmed that Chrome and Firefox are
working as intended.
Android fingerprints were grossly unpopular, which could a result of
incorrect merge, but either way we'll remove them for now.
2018-06-15 17:25:21 -04:00
Michael Munday
567b737092 crypto, internal/cpu: fix s390x AES feature detection and update SHA implementations
Hardware AES support in Go on s390x currently requires ECB, CBC
and CTR modes be available. It also requires that either the
GHASH or GCM facilities are available. The existing checks missed
some of these constraints.

While we're here simplify the cpu package on s390x, moving masking
code out of assembly and into Go code. Also, update SHA-{1,256,512}
implementations to use the cpu package since that is now trivial.

Finally I also added a test for internal/cpu on s390x which loads
/proc/cpuinfo and checks it against the flags set by internal/cpu.

Updates #25822 for changes to vet whitelist.

Change-Id: Iac4183f571643209e027f730989c60a811c928eb
Reviewed-on: https://go-review.googlesource.com/114397
Run-TryBot: Michael Munday <mike.munday@ibm.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2018-06-11 11:41:31 +00:00
Filippo Valsorda
f6b235c8c5 crypto/tls: expand docs on client-side session ticket support
Users are sometimes confused why session tickets are not enabled even if
SessionTicketsDisabled is false.

Change-Id: I3b783d2cf3eed693a3ad6acb40a8003db7e0b648
Reviewed-on: https://go-review.googlesource.com/117255
Reviewed-by: Adam Langley <agl@golang.org>
2018-06-07 21:15:41 +00:00
Tim Cooper
99371c4e8c all: update comment URLs from HTTP to HTTPS, where possible
Each URL was manually verified to ensure it did not serve up incorrect
content.

Change-Id: I4dc846227af95a73ee9a3074d0c379ff0fa955df
Reviewed-on: https://go-review.googlesource.com/115798
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Run-TryBot: Ian Lance Taylor <iant@golang.org>
2018-06-01 21:52:00 +00:00
Anit Gandhi
2da7203eca crypto/{aes,internal/cipherhw,tls}: use common internal/cpu in place of cipherhw
When the internal/cpu package was introduced, the AES package still used
the custom crypto/internal/cipherhw package for amd64 and s390x. This
change removes that package entirely in favor of directly referencing the
cpu feature flags set and exposed by the internal/cpu package. In
addition, 5 new flags have been added to the internal/cpu s390x struct
for detecting various cipher message (KM) features.

Change-Id: I77cdd8bc1b04ab0e483b21bf1879b5801a4ba5f4
GitHub-Last-Rev: a611e3ecb1f480dcbfce3cb0c8c9e4058f56c1a4
GitHub-Pull-Request: golang/go#24766
Reviewed-on: https://go-review.googlesource.com/105695
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2018-05-23 22:22:09 +00:00
Kevin Burke
a7f5c0823b crypto/tls: add examples for [Load]X509KeyPair
I was confused about how to start an HTTP server if the server
cert/key are in memory, not on disk. I thought it would be good to
show an example of how to use these two functions to accomplish that.

example-cert.pem and example-key.pem were generated using
crypto/tls/generate_cert.go.

Change-Id: I850e1282fb1c38aff8bd9aeb51988d21fe307584
Reviewed-on: https://go-review.googlesource.com/72252
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2018-04-30 17:25:27 +00:00
Sergey Frolov
871f61f85e Add EnableWeakCiphers(): to enable old CBC ciphers 2018-04-26 16:55:47 -06:00