]> Cypherpunks repositories - gostls13.git/commitdiff
crypto/cipher: enforce message size limits for GCM.
authorAdam Langley <agl@golang.org>
Thu, 1 Sep 2016 23:00:25 +0000 (16:00 -0700)
committerAdam Langley <agl@golang.org>
Fri, 2 Sep 2016 16:23:15 +0000 (16:23 +0000)
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: Andrew Gerrand <adg@golang.org>
src/crypto/aes/aes_gcm.go
src/crypto/cipher/gcm.go

index a894a68293e185e77337c6583ff7cecf1cbdbaeb..5e2de02710d989fe7e9f15753efb8e18b9ed6ede 100644 (file)
@@ -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]
 
index 3868d7123a1d9eacf1455dac2b253b7071118a9f..cfc5769a80e7718377965ab2f824a49296ac7b98 100644 (file)
@@ -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]