aboutsummaryrefslogtreecommitdiff
path: root/src/pkg/crypto
diff options
context:
space:
mode:
authorRuss Cox <rsc@golang.org>2013-01-30 12:45:13 -0800
committerRuss Cox <rsc@golang.org>2013-01-30 12:45:13 -0800
commitfa2acad60379f59712cc15ea1c4192b982e69a35 (patch)
tree1e12d8e850230caa7059f7f3f78c5ecd36f00bd6 /src/pkg/crypto
parent7e9f00c80c56fe325d0c0e11c4a8ce4bc368b06e (diff)
downloadgo-fa2acad60379f59712cc15ea1c4192b982e69a35.tar.xz
crypto/cipher: avoid out of bounds error in CryptBlocks
Fixes #4699. R=golang-dev, agl CC=golang-dev https://golang.org/cl/7231065
Diffstat (limited to 'src/pkg/crypto')
-rw-r--r--src/pkg/crypto/cipher/cbc.go12
-rw-r--r--src/pkg/crypto/cipher/cipher_test.go36
2 files changed, 48 insertions, 0 deletions
diff --git a/src/pkg/crypto/cipher/cbc.go b/src/pkg/crypto/cipher/cbc.go
index 6fab9b4213..913a5643f2 100644
--- a/src/pkg/crypto/cipher/cbc.go
+++ b/src/pkg/crypto/cipher/cbc.go
@@ -42,6 +42,12 @@ func NewCBCEncrypter(b Block, iv []byte) BlockMode {
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 NewCBCDecrypter(b Block, iv []byte) BlockMode {
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++ {
diff --git a/src/pkg/crypto/cipher/cipher_test.go b/src/pkg/crypto/cipher/cipher_test.go
new file mode 100644
index 0000000000..8da5bce93f
--- /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()
+}