Commit 5a0d9ef8 authored by Brad Fitzpatrick's avatar Brad Fitzpatrick

crypto/tls, crypto/aes: remove allocations when Writing & Reading

benchmark          old ns/op     new ns/op     delta
BenchmarkTLS-4     8571          7938          -7.39%

benchmark          old MB/s     new MB/s     speedup
BenchmarkTLS-4     119.46       128.98       1.08x

benchmark          old allocs     new allocs     delta
BenchmarkTLS-4     8              0              -100.00%

benchmark          old bytes     new bytes     delta
BenchmarkTLS-4     128           0             -100.00%

On:

func BenchmarkTLS(b *testing.B) {
        b.ReportAllocs()
        b.SetBytes(1024)
        ts := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
                io.Copy(ioutil.Discard, r.Body)
        }))
        defer ts.Close()
        buf := make([]byte, 1024)
        for i := range buf {
                buf[i] = byte(i)
        }
        c, err := tls.Dial("tcp", ts.Listener.Addr().String(), &tls.Config{
                InsecureSkipVerify: true,
        })
        if err != nil {
                b.Fatal(err)
        }
        defer c.Close()
        clen := int64(b.N) * 1024
        if _, err := c.Write([]byte(
            "POST / HTTP/1.1\r\nHost: foo\r\nContent-Length: " +
            fmt.Sprint(clen) + "\r\n\r\n")); err != nil {
                b.Fatal(err)
        }
        b.ResetTimer()
        for i := 0; i < b.N; i++ {
                if _, err := c.Write(buf); err != nil {
                        b.Fatal(err)
                }
        }
}

Change-Id: I206e7e2118b97148f9751b740d8470895634d3f5
Reviewed-on: https://go-review.googlesource.com/16828Reviewed-by: 's avatarAdam Langley <agl@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
parent ac658a83
......@@ -14,11 +14,23 @@ import (
// The following functions are defined in gcm_amd64.s.
func hasGCMAsm() bool
//go:noescape
func aesEncBlock(dst, src *[16]byte, ks []uint32)
//go:noescape
func gcmAesInit(productTable *[256]byte, ks []uint32)
//go:noescape
func gcmAesData(productTable *[256]byte, data []byte, T *[16]byte)
//go:noescape
func gcmAesEnc(productTable *[256]byte, dst, src []byte, ctr, T *[16]byte, ks []uint32)
//go:noescape
func gcmAesDec(productTable *[256]byte, dst, src []byte, ctr, T *[16]byte, ks []uint32)
//go:noescape
func gcmAesFinish(productTable *[256]byte, tagMask, T *[16]byte, pLen, dLen uint64)
const (
......
......@@ -98,12 +98,13 @@ func (c *Conn) SetWriteDeadline(t time.Time) error {
type halfConn struct {
sync.Mutex
err error // first permanent error
version uint16 // protocol version
cipher interface{} // cipher algorithm
mac macFunction
seq [8]byte // 64-bit sequence number
bfree *block // list of free blocks
err error // first permanent error
version uint16 // protocol version
cipher interface{} // cipher algorithm
mac macFunction
seq [8]byte // 64-bit sequence number
bfree *block // list of free blocks
additionalData [13]byte // to avoid allocs; interface method args escape
nextCipher interface{} // next encryption state
nextMac macFunction // next MAC algorithm
......@@ -262,14 +263,13 @@ func (hc *halfConn) decrypt(b *block) (ok bool, prefixLen int, alertValue alert)
nonce := payload[:8]
payload = payload[8:]
var additionalData [13]byte
copy(additionalData[:], hc.seq[:])
copy(additionalData[8:], b.data[:3])
copy(hc.additionalData[:], hc.seq[:])
copy(hc.additionalData[8:], b.data[:3])
n := len(payload) - c.Overhead()
additionalData[11] = byte(n >> 8)
additionalData[12] = byte(n)
hc.additionalData[11] = byte(n >> 8)
hc.additionalData[12] = byte(n)
var err error
payload, err = c.Open(payload[:0], nonce, payload, additionalData[:])
payload, err = c.Open(payload[:0], nonce, payload, hc.additionalData[:])
if err != nil {
return false, 0, alertBadRecordMAC
}
......@@ -378,13 +378,12 @@ func (hc *halfConn) encrypt(b *block, explicitIVLen int) (bool, alert) {
payload := b.data[recordHeaderLen+explicitIVLen:]
payload = payload[:payloadLen]
var additionalData [13]byte
copy(additionalData[:], hc.seq[:])
copy(additionalData[8:], b.data[:3])
additionalData[11] = byte(payloadLen >> 8)
additionalData[12] = byte(payloadLen)
copy(hc.additionalData[:], hc.seq[:])
copy(hc.additionalData[8:], b.data[:3])
hc.additionalData[11] = byte(payloadLen >> 8)
hc.additionalData[12] = byte(payloadLen)
c.Seal(payload[:0], nonce, payload, additionalData[:])
c.Seal(payload[:0], nonce, payload, hc.additionalData[:])
case cbcMode:
blockSize := c.BlockSize()
if explicitIVLen > 0 {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment