From: Adam Langley Date: Thu, 1 Sep 2016 23:00:25 +0000 (-0700) Subject: crypto/cipher: enforce message size limits for GCM. X-Git-Tag: go1.8beta1~1517 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=210ac4d5e0fea2bfd4287b0865104bdaaeaffe05;p=gostls13.git 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 TryBot-Result: Gobot Gobot Reviewed-by: Andrew Gerrand --- diff --git a/src/crypto/aes/aes_gcm.go b/src/crypto/aes/aes_gcm.go index a894a68293..5e2de02710 100644 --- a/src/crypto/aes/aes_gcm.go +++ b/src/crypto/aes/aes_gcm.go @@ -99,6 +99,9 @@ func (g *gcmAsm) Seal(dst, nonce, plaintext, data []byte) []byte { if len(nonce) != g.nonceSize { 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 @@ -137,6 +140,10 @@ func (g *gcmAsm) Open(dst, nonce, ciphertext, data []byte) ([]byte, error) { if len(ciphertext) < gcmTagSize { return nil, errOpen } + if uint64(len(ciphertext)) > ((1<<32)-2)*BlockSize+gcmTagSize { + return nil, errOpen + } + tag := ciphertext[len(ciphertext)-gcmTagSize:] ciphertext = ciphertext[:len(ciphertext)-gcmTagSize] diff --git a/src/crypto/cipher/gcm.go b/src/crypto/cipher/gcm.go index 3868d7123a..cfc5769a80 100644 --- a/src/crypto/cipher/gcm.go +++ b/src/crypto/cipher/gcm.go @@ -135,6 +135,10 @@ func (g *gcm) Seal(dst, nonce, plaintext, data []byte) []byte { if len(nonce) != g.nonceSize { 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) var counter, tagMask [gcmBlockSize]byte @@ -159,6 +163,10 @@ func (g *gcm) Open(dst, nonce, ciphertext, data []byte) ([]byte, error) { if len(ciphertext) < gcmTagSize { return nil, errOpen } + if uint64(len(ciphertext)) > ((1<<32)-2)*uint64(g.cipher.BlockSize())+gcmTagSize { + return nil, errOpen + } + tag := ciphertext[len(ciphertext)-gcmTagSize:] ciphertext = ciphertext[:len(ciphertext)-gcmTagSize]