]> Cypherpunks repositories - gostls13.git/commitdiff
[release-branch.go1.7] crypto/{aes,cipher}: fix panic in CBC on s390x when src length...
authorMichael Munday <munday@ca.ibm.com>
Thu, 13 Oct 2016 21:08:54 +0000 (17:08 -0400)
committerChris Broadfoot <cbro@golang.org>
Mon, 17 Oct 2016 20:25:13 +0000 (20:25 +0000)
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>

src/crypto/aes/cbc_s390x.go
src/crypto/cipher/cipher_test.go

index 427b30b2a7023ca2af4fdad9a76e13492ca141ff..739e1febc310f2d3232c6187e2dd3c4e17a3ec56 100644 (file)
@@ -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) {
index 1faa7b87e526a0313d8838c77ef40239b56763bc..4d7cd6b5dd93de98d1feb0da38487253495c93b9 100644 (file)
@@ -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)
+       }
+}