}
func (h *hmac) Sum(in []byte) []byte {
- sum := h.inner.Sum(nil)
+ origLen := len(in)
+ in = h.inner.Sum(in)
h.tmpPad(0x5c)
- for i, b := range sum {
- h.tmp[padSize+i] = b
- }
+ copy(h.tmp[padSize:], in[origLen:])
h.outer.Reset()
h.outer.Write(h.tmp)
- return h.outer.Sum(in)
+ return h.outer.Sum(in[:origLen])
}
func (h *hmac) Write(p []byte) (n int, err error) {
func (d0 *digest) Sum(in []byte) []byte {
// Make a copy of d0 so that caller can keep writing and summing.
- d := new(digest)
- *d = *d0
+ d := *d0
// Padding. Add a 1 bit and 0 bits until 56 bytes mod 64.
len := d.len
panic("d.nx != 0")
}
- for _, s := range d.s {
- in = append(in, byte(s>>0))
- in = append(in, byte(s>>8))
- in = append(in, byte(s>>16))
- in = append(in, byte(s>>24))
+ var digest [Size]byte
+ for i, s := range d.s {
+ digest[i*4] = byte(s)
+ digest[i*4+1] = byte(s >> 8)
+ digest[i*4+2] = byte(s >> 16)
+ digest[i*4+3] = byte(s >> 24)
}
- return in
+
+ return append(in, digest[:]...)
}
// 4880, section 3.7.1.2) using the given hash, input passphrase and salt.
func Salted(out []byte, h hash.Hash, in []byte, salt []byte) {
done := 0
+ var digest []byte
for i := 0; done < len(out); i++ {
h.Reset()
}
h.Write(salt)
h.Write(in)
- n := copy(out[done:], h.Sum(nil))
+ digest = h.Sum(digest[:0])
+ n := copy(out[done:], digest)
done += n
}
}
}
done := 0
+ var digest []byte
for i := 0; done < len(out); i++ {
h.Reset()
for j := 0; j < i; j++ {
written += len(combined)
}
}
- n := copy(out[done:], h.Sum(nil))
+ digest = h.Sum(digest[:0])
+ n := copy(out[done:], digest)
done += n
}
}
func (d0 *digest) Sum(in []byte) []byte {
// Make a copy of d0 so that caller can keep writing and summing.
- d := new(digest)
- *d = *d0
+ d := *d0
// Padding. Add a 1 bit and 0 bits until 56 bytes mod 64.
tc := d.tc
panic("d.nx != 0")
}
- for _, s := range d.s {
- in = append(in, byte(s))
- in = append(in, byte(s>>8))
- in = append(in, byte(s>>16))
- in = append(in, byte(s>>24))
+ var digest [Size]byte
+ for i, s := range d.s {
+ digest[i*4] = byte(s)
+ digest[i*4+1] = byte(s >> 8)
+ digest[i*4+2] = byte(s >> 16)
+ digest[i*4+3] = byte(s >> 24)
}
- return in
+
+ return append(in, digest[:]...)
}
// specified in PKCS#1 v2.1.
func mgf1XOR(out []byte, hash hash.Hash, seed []byte) {
var counter [4]byte
+ var digest []byte
done := 0
for done < len(out) {
hash.Write(seed)
hash.Write(counter[0:4])
- digest := hash.Sum(nil)
+ digest = hash.Sum(digest[:0])
hash.Reset()
for i := 0; i < len(digest) && done < len(out); i++ {
func (d0 *digest) Sum(in []byte) []byte {
// Make a copy of d0 so that caller can keep writing and summing.
- d := new(digest)
- *d = *d0
+ d := *d0
// Padding. Add a 1 bit and 0 bits until 56 bytes mod 64.
len := d.len
panic("d.nx != 0")
}
- for _, s := range d.h {
- in = append(in, byte(s>>24))
- in = append(in, byte(s>>16))
- in = append(in, byte(s>>8))
- in = append(in, byte(s))
+ var digest [Size]byte
+ for i, s := range d.h {
+ digest[i*4] = byte(s >> 24)
+ digest[i*4+1] = byte(s >> 16)
+ digest[i*4+2] = byte(s >> 8)
+ digest[i*4+3] = byte(s)
}
- return in
+
+ return append(in, digest[:]...)
}
func (d0 *digest) Sum(in []byte) []byte {
// Make a copy of d0 so that caller can keep writing and summing.
- d := new(digest)
- *d = *d0
+ d := *d0
// Padding. Add a 1 bit and 0 bits until 56 bytes mod 64.
len := d.len
}
h := d.h[:]
+ size := Size
if d.is224 {
h = d.h[:7]
+ size = Size224
}
- for _, s := range h {
- in = append(in, byte(s>>24))
- in = append(in, byte(s>>16))
- in = append(in, byte(s>>8))
- in = append(in, byte(s))
+
+ var digest [Size]byte
+ for i, s := range h {
+ digest[i*4] = byte(s >> 24)
+ digest[i*4+1] = byte(s >> 16)
+ digest[i*4+2] = byte(s >> 8)
+ digest[i*4+3] = byte(s)
}
- return in
+
+ return append(in, digest[:size]...)
}
}
h := d.h[:]
+ size := Size
if d.is384 {
h = d.h[:6]
+ size = Size384
}
- for _, s := range h {
- in = append(in, byte(s>>56))
- in = append(in, byte(s>>48))
- in = append(in, byte(s>>40))
- in = append(in, byte(s>>32))
- in = append(in, byte(s>>24))
- in = append(in, byte(s>>16))
- in = append(in, byte(s>>8))
- in = append(in, byte(s))
+
+ var digest [Size]byte
+ for i, s := range h {
+ digest[i*8] = byte(s >> 56)
+ digest[i*8+1] = byte(s >> 48)
+ digest[i*8+2] = byte(s >> 40)
+ digest[i*8+3] = byte(s >> 32)
+ digest[i*8+4] = byte(s >> 24)
+ digest[i*8+5] = byte(s >> 16)
+ digest[i*8+6] = byte(s >> 8)
+ digest[i*8+7] = byte(s)
}
- return in
+
+ return append(in, digest[:size]...)
}
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
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
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.
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 {
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
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
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:]
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)
}
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)