]> Cypherpunks repositories - gostls13.git/commitdiff
crypto/aes: fix overrun in assembly encrypt/decrypt
authorRuss Cox <rsc@golang.org>
Fri, 9 May 2014 19:40:55 +0000 (15:40 -0400)
committerRuss Cox <rsc@golang.org>
Fri, 9 May 2014 19:40:55 +0000 (15:40 -0400)
Fixes #7928.

LGTM=bradfitz
R=golang-codereviews
CC=agl, bradfitz, golang-codereviews
https://golang.org/cl/91320043

src/pkg/crypto/aes/aes_test.go
src/pkg/crypto/aes/cipher.go
src/pkg/crypto/aes/cipher_asm.go

index 6261dd09fb5e3d230e6a7c663dbc4bb31f51c38a..363180931c77182c73e620bcc51557d3881066d8 100644 (file)
@@ -354,6 +354,34 @@ func TestCipherDecrypt(t *testing.T) {
        }
 }
 
+// Test short input/output.
+// Assembly used to not notice.
+// See issue 7928.
+func TestShortBlocks(t *testing.T) {
+       bytes := func(n int) []byte { return make([]byte, n) }
+
+       c, _ := NewCipher(bytes(16))
+
+       mustPanic(t, "crypto/aes: input not full block", func() { c.Encrypt(bytes(1), bytes(1)) })
+       mustPanic(t, "crypto/aes: input not full block", func() { c.Decrypt(bytes(1), bytes(1)) })
+       mustPanic(t, "crypto/aes: input not full block", func() { c.Encrypt(bytes(100), bytes(1)) })
+       mustPanic(t, "crypto/aes: input not full block", func() { c.Decrypt(bytes(100), bytes(1)) })
+       mustPanic(t, "crypto/aes: output not full block", func() { c.Encrypt(bytes(1), bytes(100)) })
+       mustPanic(t, "crypto/aes: output not full block", func() { c.Decrypt(bytes(1), bytes(100)) })
+}
+
+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()
+}
+
 func BenchmarkEncrypt(b *testing.B) {
        tt := encryptTests[0]
        c, err := NewCipher(tt.key)
index d931134a70ef176cc545ab03026f993ddc2c3db9..2c6bb0a89c7b753359f862081c0f858879b7c99b 100644 (file)
@@ -46,9 +46,21 @@ func NewCipher(key []byte) (cipher.Block, error) {
 func (c *aesCipher) BlockSize() int { return BlockSize }
 
 func (c *aesCipher) Encrypt(dst, src []byte) {
+       if len(src) < BlockSize {
+               panic("crypto/aes: input not full block")
+       }
+       if len(dst) < BlockSize {
+               panic("crypto/aes: output not full block")
+       }
        encryptBlock(c.enc, dst, src)
 }
 
 func (c *aesCipher) Decrypt(dst, src []byte) {
+       if len(src) < BlockSize {
+               panic("crypto/aes: input not full block")
+       }
+       if len(dst) < BlockSize {
+               panic("crypto/aes: output not full block")
+       }
        decryptBlock(c.dec, dst, src)
 }
index 21369fc382c43462d5c6c3d20585547bf355ccec..964eaaa6f886f9f474be72e1832fa5a7c95d7e1f 100644 (file)
@@ -21,6 +21,7 @@ func encryptBlock(xk []uint32, dst, src []byte) {
                encryptBlockGo(xk, dst, src)
        }
 }
+
 func decryptBlock(xk []uint32, dst, src []byte) {
        if useAsm {
                decryptBlockAsm(len(xk)/4-1, &xk[0], &dst[0], &src[0])
@@ -28,6 +29,7 @@ func decryptBlock(xk []uint32, dst, src []byte) {
                decryptBlockGo(xk, dst, src)
        }
 }
+
 func expandKey(key []byte, enc, dec []uint32) {
        if useAsm {
                rounds := 10