Commit 210ac4d5 authored by Adam Langley's avatar Adam Langley

crypto/cipher: enforce message size limits for GCM.

The maximum input plaintext for GCM is 64GiB - 64. Since the GCM
interface is one-shot, it's very hard to hit this in Go (one would need
a 64GiB buffer in memory), but we should still enforce this limit.

Thanks to Quan Nguyen for pointing it out.

Change-Id: Icced47bf8d4d5dfbefa165cf13e893205c9577b8
Reviewed-on: https://go-review.googlesource.com/28410
Run-TryBot: Adam Langley <agl@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: default avatarAndrew Gerrand <adg@golang.org>
parent 03cff2e1
...@@ -99,6 +99,9 @@ func (g *gcmAsm) Seal(dst, nonce, plaintext, data []byte) []byte { ...@@ -99,6 +99,9 @@ func (g *gcmAsm) Seal(dst, nonce, plaintext, data []byte) []byte {
if len(nonce) != g.nonceSize { if len(nonce) != g.nonceSize {
panic("cipher: incorrect nonce length given to GCM") panic("cipher: incorrect nonce length given to GCM")
} }
if uint64(len(plaintext)) > ((1<<32)-2)*BlockSize {
panic("cipher: message too large for GCM")
}
var counter, tagMask [gcmBlockSize]byte var counter, tagMask [gcmBlockSize]byte
...@@ -137,6 +140,10 @@ func (g *gcmAsm) Open(dst, nonce, ciphertext, data []byte) ([]byte, error) { ...@@ -137,6 +140,10 @@ func (g *gcmAsm) Open(dst, nonce, ciphertext, data []byte) ([]byte, error) {
if len(ciphertext) < gcmTagSize { if len(ciphertext) < gcmTagSize {
return nil, errOpen return nil, errOpen
} }
if uint64(len(ciphertext)) > ((1<<32)-2)*BlockSize+gcmTagSize {
return nil, errOpen
}
tag := ciphertext[len(ciphertext)-gcmTagSize:] tag := ciphertext[len(ciphertext)-gcmTagSize:]
ciphertext = ciphertext[:len(ciphertext)-gcmTagSize] ciphertext = ciphertext[:len(ciphertext)-gcmTagSize]
......
...@@ -135,6 +135,10 @@ func (g *gcm) Seal(dst, nonce, plaintext, data []byte) []byte { ...@@ -135,6 +135,10 @@ func (g *gcm) Seal(dst, nonce, plaintext, data []byte) []byte {
if len(nonce) != g.nonceSize { if len(nonce) != g.nonceSize {
panic("cipher: incorrect nonce length given to GCM") panic("cipher: incorrect nonce length given to GCM")
} }
if uint64(len(plaintext)) > ((1<<32)-2)*uint64(g.cipher.BlockSize()) {
panic("cipher: message too large for GCM")
}
ret, out := sliceForAppend(dst, len(plaintext)+gcmTagSize) ret, out := sliceForAppend(dst, len(plaintext)+gcmTagSize)
var counter, tagMask [gcmBlockSize]byte var counter, tagMask [gcmBlockSize]byte
...@@ -159,6 +163,10 @@ func (g *gcm) Open(dst, nonce, ciphertext, data []byte) ([]byte, error) { ...@@ -159,6 +163,10 @@ func (g *gcm) Open(dst, nonce, ciphertext, data []byte) ([]byte, error) {
if len(ciphertext) < gcmTagSize { if len(ciphertext) < gcmTagSize {
return nil, errOpen return nil, errOpen
} }
if uint64(len(ciphertext)) > ((1<<32)-2)*uint64(g.cipher.BlockSize())+gcmTagSize {
return nil, errOpen
}
tag := ciphertext[len(ciphertext)-gcmTagSize:] tag := ciphertext[len(ciphertext)-gcmTagSize:]
ciphertext = ciphertext[:len(ciphertext)-gcmTagSize] ciphertext = ciphertext[:len(ciphertext)-gcmTagSize]
......
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