Skip to content

Commit 83c378c

Browse files
committed
ssh: update to use new ChaCha20 API
Use the new streaming API added in CL 104856. Change-Id: I6453a54a9739f20fc4d05f476c6e26f720ccd354 Reviewed-on: https://go-review.googlesource.com/108656 Run-TryBot: Michael Munday <[email protected]> Reviewed-by: Brad Fitzpatrick <[email protected]>
1 parent 12dd70c commit 83c378c

File tree

1 file changed

+21
-22
lines changed

1 file changed

+21
-22
lines changed

ssh/cipher.go

Lines changed: 21 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import (
1616
"hash"
1717
"io"
1818
"io/ioutil"
19+
"math/bits"
1920

2021
"golang.org/x/crypto/internal/chacha20"
2122
"golang.org/x/crypto/poly1305"
@@ -641,8 +642,8 @@ const chacha20Poly1305ID = "[email protected]"
641642
// the methods here also implement padding, which RFC4253 Section 6
642643
// also requires of stream ciphers.
643644
type chacha20Poly1305Cipher struct {
644-
lengthKey [32]byte
645-
contentKey [32]byte
645+
lengthKey [8]uint32
646+
contentKey [8]uint32
646647
buf []byte
647648
}
648649

@@ -655,28 +656,29 @@ func newChaCha20Cipher(key, unusedIV, unusedMACKey []byte, unusedAlgs directionA
655656
buf: make([]byte, 256),
656657
}
657658

658-
copy(c.contentKey[:], key[:32])
659-
copy(c.lengthKey[:], key[32:])
659+
for i := range c.contentKey {
660+
c.contentKey[i] = binary.LittleEndian.Uint32(key[i*4 : (i+1)*4])
661+
}
662+
for i := range c.contentKey {
663+
c.lengthKey[i] = binary.LittleEndian.Uint32(key[(i+8)*4 : (i+9)*4])
664+
}
660665
return c, nil
661666
}
662667

663-
// The Poly1305 key is obtained by encrypting 32 0-bytes.
664-
var chacha20PolyKeyInput [32]byte
665-
666668
func (c *chacha20Poly1305Cipher) readPacket(seqNum uint32, r io.Reader) ([]byte, error) {
667-
var counter [16]byte
668-
binary.BigEndian.PutUint64(counter[8:], uint64(seqNum))
669-
669+
nonce := [3]uint32{0, 0, bits.ReverseBytes32(seqNum)}
670+
s := chacha20.New(c.contentKey, nonce)
670671
var polyKey [32]byte
671-
chacha20.XORKeyStream(polyKey[:], chacha20PolyKeyInput[:], &counter, &c.contentKey)
672+
s.XORKeyStream(polyKey[:], polyKey[:])
673+
s.Advance() // skip next 32 bytes
672674

673675
encryptedLength := c.buf[:4]
674676
if _, err := io.ReadFull(r, encryptedLength); err != nil {
675677
return nil, err
676678
}
677679

678680
var lenBytes [4]byte
679-
chacha20.XORKeyStream(lenBytes[:], encryptedLength, &counter, &c.lengthKey)
681+
chacha20.New(c.lengthKey, nonce).XORKeyStream(lenBytes[:], encryptedLength)
680682

681683
length := binary.BigEndian.Uint32(lenBytes[:])
682684
if length > maxPacket {
@@ -702,10 +704,8 @@ func (c *chacha20Poly1305Cipher) readPacket(seqNum uint32, r io.Reader) ([]byte,
702704
return nil, errors.New("ssh: MAC failure")
703705
}
704706

705-
counter[0] = 1
706-
707707
plain := c.buf[4:contentEnd]
708-
chacha20.XORKeyStream(plain, plain, &counter, &c.contentKey)
708+
s.XORKeyStream(plain, plain)
709709

710710
padding := plain[0]
711711
if padding < 4 {
@@ -724,11 +724,11 @@ func (c *chacha20Poly1305Cipher) readPacket(seqNum uint32, r io.Reader) ([]byte,
724724
}
725725

726726
func (c *chacha20Poly1305Cipher) writePacket(seqNum uint32, w io.Writer, rand io.Reader, payload []byte) error {
727-
var counter [16]byte
728-
binary.BigEndian.PutUint64(counter[8:], uint64(seqNum))
729-
727+
nonce := [3]uint32{0, 0, bits.ReverseBytes32(seqNum)}
728+
s := chacha20.New(c.contentKey, nonce)
730729
var polyKey [32]byte
731-
chacha20.XORKeyStream(polyKey[:], chacha20PolyKeyInput[:], &counter, &c.contentKey)
730+
s.XORKeyStream(polyKey[:], polyKey[:])
731+
s.Advance() // skip next 32 bytes
732732

733733
// There is no blocksize, so fall back to multiple of 8 byte
734734
// padding, as described in RFC 4253, Sec 6.
@@ -748,16 +748,15 @@ func (c *chacha20Poly1305Cipher) writePacket(seqNum uint32, w io.Writer, rand io
748748
}
749749

750750
binary.BigEndian.PutUint32(c.buf, uint32(1+len(payload)+padding))
751-
chacha20.XORKeyStream(c.buf, c.buf[:4], &counter, &c.lengthKey)
751+
chacha20.New(c.lengthKey, nonce).XORKeyStream(c.buf, c.buf[:4])
752752
c.buf[4] = byte(padding)
753753
copy(c.buf[5:], payload)
754754
packetEnd := 5 + len(payload) + padding
755755
if _, err := io.ReadFull(rand, c.buf[5+len(payload):packetEnd]); err != nil {
756756
return err
757757
}
758758

759-
counter[0] = 1
760-
chacha20.XORKeyStream(c.buf[4:], c.buf[4:packetEnd], &counter, &c.contentKey)
759+
s.XORKeyStream(c.buf[4:], c.buf[4:packetEnd])
761760

762761
var mac [poly1305.TagSize]byte
763762
poly1305.Sum(&mac, c.buf[:packetEnd], &polyKey)

0 commit comments

Comments
 (0)