Skip to content

Commit 61f1a38

Browse files
committed
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 <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Brad Fitzpatrick <[email protected]>
1 parent 714318b commit 61f1a38

File tree

2 files changed

+57
-1
lines changed

2 files changed

+57
-1
lines changed

src/crypto/aes/cbc_s390x.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,9 @@ func (x *cbc) CryptBlocks(dst, src []byte) {
4848
if len(dst) < len(src) {
4949
panic("crypto/cipher: output smaller than input")
5050
}
51-
cryptBlocksChain(x.c, &x.iv[0], &x.b.key[0], &dst[0], &src[0], len(src))
51+
if len(src) > 0 {
52+
cryptBlocksChain(x.c, &x.iv[0], &x.b.key[0], &dst[0], &src[0], len(src))
53+
}
5254
}
5355

5456
func (x *cbc) SetIV(iv []byte) {

src/crypto/cipher/cipher_test.go

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,10 @@
55
package cipher_test
66

77
import (
8+
"bytes"
89
"crypto/aes"
910
"crypto/cipher"
11+
"crypto/des"
1012
"testing"
1113
)
1214

@@ -34,3 +36,55 @@ func mustPanic(t *testing.T, msg string, f func()) {
3436
}()
3537
f()
3638
}
39+
40+
func TestEmptyPlaintext(t *testing.T) {
41+
var key [16]byte
42+
a, err := aes.NewCipher(key[:16])
43+
if err != nil {
44+
t.Fatal(err)
45+
}
46+
d, err := des.NewCipher(key[:8])
47+
if err != nil {
48+
t.Fatal(err)
49+
}
50+
51+
s := 16
52+
pt := make([]byte, s)
53+
ct := make([]byte, s)
54+
for i := 0; i < 16; i++ {
55+
pt[i], ct[i] = byte(i), byte(i)
56+
}
57+
58+
assertEqual := func(name string, got, want []byte) {
59+
if !bytes.Equal(got, want) {
60+
t.Fatalf("%s: got %v, want %v", name, got, want)
61+
}
62+
}
63+
64+
for _, b := range []cipher.Block{a, d} {
65+
iv := make([]byte, b.BlockSize())
66+
cbce := cipher.NewCBCEncrypter(b, iv)
67+
cbce.CryptBlocks(ct, pt[:0])
68+
assertEqual("CBC encrypt", ct, pt)
69+
70+
cbcd := cipher.NewCBCDecrypter(b, iv)
71+
cbcd.CryptBlocks(ct, pt[:0])
72+
assertEqual("CBC decrypt", ct, pt)
73+
74+
cfbe := cipher.NewCFBEncrypter(b, iv)
75+
cfbe.XORKeyStream(ct, pt[:0])
76+
assertEqual("CFB encrypt", ct, pt)
77+
78+
cfbd := cipher.NewCFBDecrypter(b, iv)
79+
cfbd.XORKeyStream(ct, pt[:0])
80+
assertEqual("CFB decrypt", ct, pt)
81+
82+
ctr := cipher.NewCTR(b, iv)
83+
ctr.XORKeyStream(ct, pt[:0])
84+
assertEqual("CTR", ct, pt)
85+
86+
ofb := cipher.NewOFB(b, iv)
87+
ofb.XORKeyStream(ct, pt[:0])
88+
assertEqual("OFB", ct, pt)
89+
}
90+
}

0 commit comments

Comments
 (0)