aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Munday <munday@ca.ibm.com>2016-10-13 17:08:54 -0400
committerChris Broadfoot <cbro@golang.org>2016-10-17 20:25:13 +0000
commitf0377a2851f13eda1993fd92d3f55d23884bdb83 (patch)
tree67492fbeddcb9ec3c23a855e8b05431c5002cb6d
parent2287d95e9b130821b61c34afb79d8541268acd9b (diff)
downloadgo-f0377a2851f13eda1993fd92d3f55d23884bdb83.tar.gz
go-f0377a2851f13eda1993fd92d3f55d23884bdb83.zip
[release-branch.go1.7] crypto/{aes,cipher}: fix panic in CBC on s390x when src length is 0
Adds a test to check that block cipher modes accept a zero-length input. Fixes #17435. Change-Id: Ie093c4cdff756b5c2dcb79342e167b3de5622389 Reviewed-on: https://go-review.googlesource.com/31070 Run-TryBot: Michael Munday <munday@ca.ibm.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org> Reviewed-on: https://go-review.googlesource.com/31291 Reviewed-by: Michael Munday <munday@ca.ibm.com> Run-TryBot: Chris Broadfoot <cbro@golang.org>
-rw-r--r--src/crypto/aes/cbc_s390x.go4
-rw-r--r--src/crypto/cipher/cipher_test.go54
2 files changed, 57 insertions, 1 deletions
diff --git a/src/crypto/aes/cbc_s390x.go b/src/crypto/aes/cbc_s390x.go
index 427b30b2a7..739e1febc3 100644
--- a/src/crypto/aes/cbc_s390x.go
+++ b/src/crypto/aes/cbc_s390x.go
@@ -48,7 +48,9 @@ func (x *cbc) CryptBlocks(dst, src []byte) {
if len(dst) < len(src) {
panic("crypto/cipher: output smaller than input")
}
- cryptBlocksChain(x.c, &x.iv[0], &x.b.key[0], &dst[0], &src[0], len(src))
+ if len(src) > 0 {
+ cryptBlocksChain(x.c, &x.iv[0], &x.b.key[0], &dst[0], &src[0], len(src))
+ }
}
func (x *cbc) SetIV(iv []byte) {
diff --git a/src/crypto/cipher/cipher_test.go b/src/crypto/cipher/cipher_test.go
index 1faa7b87e5..4d7cd6b5dd 100644
--- a/src/crypto/cipher/cipher_test.go
+++ b/src/crypto/cipher/cipher_test.go
@@ -5,8 +5,10 @@
package cipher_test
import (
+ "bytes"
"crypto/aes"
"crypto/cipher"
+ "crypto/des"
"testing"
)
@@ -34,3 +36,55 @@ func mustPanic(t *testing.T, msg string, f func()) {
}()
f()
}
+
+func TestEmptyPlaintext(t *testing.T) {
+ var key [16]byte
+ a, err := aes.NewCipher(key[:16])
+ if err != nil {
+ t.Fatal(err)
+ }
+ d, err := des.NewCipher(key[:8])
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ s := 16
+ pt := make([]byte, s)
+ ct := make([]byte, s)
+ for i := 0; i < 16; i++ {
+ pt[i], ct[i] = byte(i), byte(i)
+ }
+
+ assertEqual := func(name string, got, want []byte) {
+ if !bytes.Equal(got, want) {
+ t.Fatalf("%s: got %v, want %v", name, got, want)
+ }
+ }
+
+ for _, b := range []cipher.Block{a, d} {
+ iv := make([]byte, b.BlockSize())
+ cbce := cipher.NewCBCEncrypter(b, iv)
+ cbce.CryptBlocks(ct, pt[:0])
+ assertEqual("CBC encrypt", ct, pt)
+
+ cbcd := cipher.NewCBCDecrypter(b, iv)
+ cbcd.CryptBlocks(ct, pt[:0])
+ assertEqual("CBC decrypt", ct, pt)
+
+ cfbe := cipher.NewCFBEncrypter(b, iv)
+ cfbe.XORKeyStream(ct, pt[:0])
+ assertEqual("CFB encrypt", ct, pt)
+
+ cfbd := cipher.NewCFBDecrypter(b, iv)
+ cfbd.XORKeyStream(ct, pt[:0])
+ assertEqual("CFB decrypt", ct, pt)
+
+ ctr := cipher.NewCTR(b, iv)
+ ctr.XORKeyStream(ct, pt[:0])
+ assertEqual("CTR", ct, pt)
+
+ ofb := cipher.NewOFB(b, iv)
+ ofb.XORKeyStream(ct, pt[:0])
+ assertEqual("OFB", ct, pt)
+ }
+}