Reviewers:
golang-dev_googlegroups.com,
Message:
Hello
golan...@googlegroups.com,
I'd like you to review this change to
https://code.google.com/p/go/
Description:
crypto/cipher: avoid out of bounds error in CryptBlocks
Fixes issue 4699.
Please review this at
https://codereview.appspot.com/7231065/
Affected files:
M src/pkg/crypto/cipher/cbc.go
A src/pkg/crypto/cipher/cipher_test.go
Index: src/pkg/crypto/cipher/cbc.go
===================================================================
--- a/src/pkg/crypto/cipher/cbc.go
+++ b/src/pkg/crypto/cipher/cbc.go
@@ -42,6 +42,12 @@
func (x *cbcEncrypter) BlockSize() int { return x.blockSize }
func (x *cbcEncrypter) CryptBlocks(dst, src []byte) {
+ if len(src)%x.blockSize != 0 {
+ panic("crypto/cipher: input not full blocks")
+ }
+ if len(dst) < len(src) {
+ panic("crypto/cipher: output smaller than input")
+ }
for len(src) > 0 {
for i := 0; i < x.blockSize; i++ {
x.iv[i] ^= src[i]
@@ -70,6 +76,12 @@
func (x *cbcDecrypter) BlockSize() int { return x.blockSize }
func (x *cbcDecrypter) CryptBlocks(dst, src []byte) {
+ if len(src)%x.blockSize != 0 {
+ panic("crypto/cipher: input not full blocks")
+ }
+ if len(dst) < len(src) {
+ panic("crypto/cipher: output smaller than input")
+ }
for len(src) > 0 {
x.b.Decrypt(x.tmp, src[:x.blockSize])
for i := 0; i < x.blockSize; i++ {
Index: src/pkg/crypto/cipher/cipher_test.go
===================================================================
new file mode 100644
--- /dev/null
+++ b/src/pkg/crypto/cipher/cipher_test.go
@@ -0,0 +1,36 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package cipher_test
+
+import (
+ "crypto/aes"
+ "crypto/cipher"
+ "testing"
+)
+
+func TestCryptBlocks(t *testing.T) {
+ buf := make([]byte, 16)
+ block, _ := aes.NewCipher(buf)
+
+ mode := cipher.NewCBCDecrypter(block, buf)
+ mustPanic(t, "crypto/cipher: input not full blocks", func()
{mode.CryptBlocks(buf, buf[:3])})
+ mustPanic(t, "crypto/cipher: output smaller than input", func()
{mode.CryptBlocks(buf[:3], buf)})
+
+ mode = cipher.NewCBCEncrypter(block, buf)
+ mustPanic(t, "crypto/cipher: input not full blocks", func()
{mode.CryptBlocks(buf, buf[:3])})
+ mustPanic(t, "crypto/cipher: output smaller than input", func()
{mode.CryptBlocks(buf[:3], buf)})
+}
+
+func mustPanic(t *testing.T, msg string, f func()) {
+ defer func() {
+ err := recover()
+ if err == nil {
+ t.Errorf("function did not panic, wanted %q", msg)
+ } else if err != msg {
+ t.Errorf("got panic %v, wanted %q", err, msg)
+ }
+ }()
+ f()
+}