Skip to content

Commit bd1e6e7

Browse files
authored
Merge pull request #107 from golang-fips/dev/dagood/aes-overlap-compat
Fix AES Encrypt/Decrypt buffer overlap detection
2 parents b95716c + b2e2761 commit bd1e6e7

File tree

2 files changed

+28
-7
lines changed

2 files changed

+28
-7
lines changed

aes.go

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -138,16 +138,17 @@ func (c *aesCipher) finalize() {
138138
func (c *aesCipher) BlockSize() int { return aesBlockSize }
139139

140140
func (c *aesCipher) Encrypt(dst, src []byte) {
141-
if inexactOverlap(dst, src) {
142-
panic("crypto/cipher: invalid buffer overlap")
143-
}
144141
if len(src) < aesBlockSize {
145142
panic("crypto/aes: input not full block")
146143
}
147144
if len(dst) < aesBlockSize {
148145
panic("crypto/aes: output not full block")
149146
}
150-
147+
// Only check for overlap between the parts of src and dst that will actually be used.
148+
// This matches Go standard library behavior.
149+
if inexactOverlap(dst[:aesBlockSize], src[:aesBlockSize]) {
150+
panic("crypto/cipher: invalid buffer overlap")
151+
}
151152
if c.enc_ctx == nil {
152153
var err error
153154
c.enc_ctx, err = newCipherCtx(c.kind, C.GO_AES_ENCRYPT, c.key, nil)
@@ -163,15 +164,17 @@ func (c *aesCipher) Encrypt(dst, src []byte) {
163164
}
164165

165166
func (c *aesCipher) Decrypt(dst, src []byte) {
166-
if inexactOverlap(dst, src) {
167-
panic("crypto/cipher: invalid buffer overlap")
168-
}
169167
if len(src) < aesBlockSize {
170168
panic("crypto/aes: input not full block")
171169
}
172170
if len(dst) < aesBlockSize {
173171
panic("crypto/aes: output not full block")
174172
}
173+
// Only check for overlap between the parts of src and dst that will actually be used.
174+
// This matches Go standard library behavior.
175+
if inexactOverlap(dst[:aesBlockSize], src[:aesBlockSize]) {
176+
panic("crypto/cipher: invalid buffer overlap")
177+
}
175178
if c.dec_ctx == nil {
176179
var err error
177180
c.dec_ctx, err = newCipherCtx(c.kind, C.GO_AES_DECRYPT, c.key, nil)

aes_test.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -429,6 +429,24 @@ func TestNewCTR(t *testing.T) {
429429
}
430430
}
431431

432+
func TestCipherEncryptDecryptSharedBuffer(t *testing.T) {
433+
key := []byte{0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c}
434+
pt := []byte{0x32, 0x43, 0xf6, 0xa8, 0x88, 0x5a, 0x30, 0x8d, 0x31, 0x31, 0x98, 0xa2, 0xe0, 0x37, 0x07, 0x34}
435+
c, err := NewAESCipher(key)
436+
if err != nil {
437+
t.Fatal(err)
438+
}
439+
440+
b := append(pt, make([]byte, len(pt))...)
441+
// Keep b's length for the shared-buffer plaintext.
442+
// This test verifies that Encrypt and Decrypt only check for overlap in the
443+
// first block-length of the args, matching Go standard library behavior.
444+
bPt := b
445+
bCt := b[len(pt):]
446+
c.Encrypt(bCt, bPt)
447+
c.Decrypt(bPt, bCt)
448+
}
449+
432450
func BenchmarkAES_Encrypt(b *testing.B) {
433451
key := []byte{0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c}
434452
in := []byte{0x32, 0x43, 0xf6, 0xa8, 0x88, 0x5a, 0x30, 0x8d, 0x31, 0x31, 0x98, 0xa2, 0xe0, 0x37, 0x07, 0x34}

0 commit comments

Comments
 (0)