From ba3c11f6db2a20e5e2a45785d3a34fbde4c02d93 Mon Sep 17 00:00:00 2001 From: Adam Langley Date: Tue, 6 Dec 2011 18:25:14 -0500 Subject: [PATCH] crypto: allocate less. The code in hash functions themselves could write directly into the output buffer for a savings of about 50ns. But it's a little ugly so I wasted a copy. R=bradfitz CC=golang-dev https://golang.org/cl/5440111 --- cipher_suites.go | 14 +++++++------- conn.go | 9 +++++++-- handshake_client.go | 8 ++++---- handshake_server.go | 6 +++--- 4 files changed, 21 insertions(+), 16 deletions(-) diff --git a/cipher_suites.go b/cipher_suites.go index afe5129..914491d 100644 --- a/cipher_suites.go +++ b/cipher_suites.go @@ -96,7 +96,7 @@ func macSHA1(version uint16, key []byte) macFunction { type macFunction interface { Size() int - MAC(seq, data []byte) []byte + MAC(digestBuf, seq, data []byte) []byte } // ssl30MAC implements the SSLv3 MAC function, as defined in @@ -114,7 +114,7 @@ var ssl30Pad1 = [48]byte{0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0 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} -func (s ssl30MAC) MAC(seq, record []byte) []byte { +func (s ssl30MAC) MAC(digestBuf, seq, record []byte) []byte { padLength := 48 if s.h.Size() == 20 { padLength = 40 @@ -127,13 +127,13 @@ func (s ssl30MAC) MAC(seq, record []byte) []byte { s.h.Write(record[:1]) s.h.Write(record[3:5]) s.h.Write(record[recordHeaderLen:]) - digest := s.h.Sum(nil) + digestBuf = s.h.Sum(digestBuf[:0]) s.h.Reset() s.h.Write(s.key) s.h.Write(ssl30Pad2[:padLength]) - s.h.Write(digest) - return s.h.Sum(nil) + s.h.Write(digestBuf) + return s.h.Sum(digestBuf[:0]) } // tls10MAC implements the TLS 1.0 MAC function. RFC 2246, section 6.2.3. @@ -145,11 +145,11 @@ func (s tls10MAC) Size() int { return s.h.Size() } -func (s tls10MAC) MAC(seq, record []byte) []byte { +func (s tls10MAC) MAC(digestBuf, seq, record []byte) []byte { s.h.Reset() s.h.Write(seq) s.h.Write(record) - return s.h.Sum(nil) + return s.h.Sum(digestBuf[:0]) } func rsaKA() keyAgreement { diff --git a/conn.go b/conn.go index b8fa273..6a03fa8 100644 --- a/conn.go +++ b/conn.go @@ -118,6 +118,9 @@ type halfConn struct { nextCipher interface{} // next encryption state nextMac macFunction // next MAC algorithm + + // used to save allocating a new buffer for each MAC. + inDigestBuf, outDigestBuf []byte } // prepareCipherSpec sets the encryption and MAC states @@ -280,12 +283,13 @@ func (hc *halfConn) decrypt(b *block) (bool, alert) { b.data[4] = byte(n) b.resize(recordHeaderLen + n) remoteMAC := payload[n:] - localMAC := hc.mac.MAC(hc.seq[0:], b.data) + localMAC := hc.mac.MAC(hc.inDigestBuf, hc.seq[0:], b.data) hc.incSeq() if subtle.ConstantTimeCompare(localMAC, remoteMAC) != 1 || paddingGood != 255 { return false, alertBadRecordMAC } + hc.inDigestBuf = localMAC } return true, 0 @@ -312,12 +316,13 @@ func padToBlockSize(payload []byte, blockSize int) (prefix, finalBlock []byte) { func (hc *halfConn) encrypt(b *block) (bool, alert) { // mac if hc.mac != nil { - mac := hc.mac.MAC(hc.seq[0:], b.data) + mac := hc.mac.MAC(hc.outDigestBuf, hc.seq[0:], b.data) hc.incSeq() n := len(b.data) b.resize(n + len(mac)) copy(b.data[n:], mac) + hc.outDigestBuf = mac } payload := b.data[recordHeaderLen:] diff --git a/handshake_client.go b/handshake_client.go index b4337f2..e39e59c 100644 --- a/handshake_client.go +++ b/handshake_client.go @@ -231,10 +231,10 @@ func (c *Conn) clientHandshake() error { if cert != nil { certVerify := new(certificateVerifyMsg) - var digest [36]byte - copy(digest[0:16], finishedHash.serverMD5.Sum(nil)) - copy(digest[16:36], finishedHash.serverSHA1.Sum(nil)) - signed, err := rsa.SignPKCS1v15(c.config.rand(), c.config.Certificates[0].PrivateKey, crypto.MD5SHA1, digest[0:]) + digest := make([]byte, 0, 36) + digest = finishedHash.serverMD5.Sum(digest) + digest = finishedHash.serverSHA1.Sum(digest) + signed, err := rsa.SignPKCS1v15(c.config.rand(), c.config.Certificates[0].PrivateKey, crypto.MD5SHA1, digest) if err != nil { return c.sendAlert(alertInternalError) } diff --git a/handshake_server.go b/handshake_server.go index bbb23c0..89c000d 100644 --- a/handshake_server.go +++ b/handshake_server.go @@ -234,9 +234,9 @@ FindCipherSuite: return c.sendAlert(alertUnexpectedMessage) } - digest := make([]byte, 36) - copy(digest[0:16], finishedHash.serverMD5.Sum(nil)) - copy(digest[16:36], finishedHash.serverSHA1.Sum(nil)) + digest := make([]byte, 0, 36) + digest = finishedHash.serverMD5.Sum(digest) + digest = finishedHash.serverSHA1.Sum(digest) err = rsa.VerifyPKCS1v15(pub, crypto.MD5SHA1, digest, certVerify.signature) if err != nil { c.sendAlert(alertBadCertificate)