Commit 3e8ed96c authored by Russ Cox's avatar Russ Cox

crypto/aes: fix overrun in assembly encrypt/decrypt

Fixes #7928.

LGTM=bradfitz
R=golang-codereviews
CC=agl, bradfitz, golang-codereviews
https://golang.org/cl/91320043
parent c99dce2b
...@@ -354,6 +354,34 @@ func TestCipherDecrypt(t *testing.T) { ...@@ -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) { func BenchmarkEncrypt(b *testing.B) {
tt := encryptTests[0] tt := encryptTests[0]
c, err := NewCipher(tt.key) c, err := NewCipher(tt.key)
......
...@@ -46,9 +46,21 @@ func NewCipher(key []byte) (cipher.Block, error) { ...@@ -46,9 +46,21 @@ func NewCipher(key []byte) (cipher.Block, error) {
func (c *aesCipher) BlockSize() int { return BlockSize } func (c *aesCipher) BlockSize() int { return BlockSize }
func (c *aesCipher) Encrypt(dst, src []byte) { 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) encryptBlock(c.enc, dst, src)
} }
func (c *aesCipher) Decrypt(dst, src []byte) { 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) decryptBlock(c.dec, dst, src)
} }
...@@ -21,6 +21,7 @@ func encryptBlock(xk []uint32, dst, src []byte) { ...@@ -21,6 +21,7 @@ func encryptBlock(xk []uint32, dst, src []byte) {
encryptBlockGo(xk, dst, src) encryptBlockGo(xk, dst, src)
} }
} }
func decryptBlock(xk []uint32, dst, src []byte) { func decryptBlock(xk []uint32, dst, src []byte) {
if useAsm { if useAsm {
decryptBlockAsm(len(xk)/4-1, &xk[0], &dst[0], &src[0]) decryptBlockAsm(len(xk)/4-1, &xk[0], &dst[0], &src[0])
...@@ -28,6 +29,7 @@ func decryptBlock(xk []uint32, dst, src []byte) { ...@@ -28,6 +29,7 @@ func decryptBlock(xk []uint32, dst, src []byte) {
decryptBlockGo(xk, dst, src) decryptBlockGo(xk, dst, src)
} }
} }
func expandKey(key []byte, enc, dec []uint32) { func expandKey(key []byte, enc, dec []uint32) {
if useAsm { if useAsm {
rounds := 10 rounds := 10
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment