Commit 1d546005 authored by Adam Langley's avatar Adam Langley

crypto/cipher: fix CFB mode.

a073d65e6f8c had a couple of bugs in the CFB mode that I missed in code review:
        1) The loop condition wasn't updated from the old version.
        2) It wasn't safe when src and dst aliased.

Fixes #6950.

R=golang-dev, hanwen
CC=golang-dev
https://golang.org/cl/42110043
parent be51b961
......@@ -16,21 +16,22 @@ type cfb struct {
}
func (x *cfb) XORKeyStream(dst, src []byte) {
for i := 0; i < len(src); i++ {
for len(src) > 0 {
if x.outUsed == len(x.out) {
x.b.Encrypt(x.out, x.next)
x.outUsed = 0
}
n := xorBytes(dst, src, x.out[x.outUsed:])
if x.decrypt {
// We can precompute a larger segment of the
// keystream on decryption. This will allow
// larger batches for xor, and we should be
// able to match CTR/OFB performance.
copy(x.next[x.outUsed:], src[:n])
} else {
copy(x.next[x.outUsed:], dst[:n])
copy(x.next[x.outUsed:], src)
}
n := xorBytes(dst, src, x.out[x.outUsed:])
if !x.decrypt {
copy(x.next[x.outUsed:], dst)
}
dst = dst[n:]
src = src[n:]
......
......@@ -19,16 +19,18 @@ func TestCFB(t *testing.T) {
return
}
plaintext := []byte("this is the plaintext")
plaintext := []byte("this is the plaintext. this is the plaintext.")
iv := make([]byte, block.BlockSize())
rand.Reader.Read(iv)
cfb := cipher.NewCFBEncrypter(block, iv)
ciphertext := make([]byte, len(plaintext))
cfb.XORKeyStream(ciphertext, plaintext)
copy(ciphertext, plaintext)
cfb.XORKeyStream(ciphertext, ciphertext)
cfbdec := cipher.NewCFBDecrypter(block, iv)
plaintextCopy := make([]byte, len(plaintext))
cfbdec.XORKeyStream(plaintextCopy, ciphertext)
copy(plaintextCopy, ciphertext)
cfbdec.XORKeyStream(plaintextCopy, plaintextCopy)
if !bytes.Equal(plaintextCopy, plaintext) {
t.Errorf("got: %x, want: %x", plaintextCopy, plaintext)
......
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