diff --git a/src/crypto/cipher/gcm.go b/src/crypto/cipher/gcm.go index c0ac9f163e..28f8b2093e 100644 --- a/src/crypto/cipher/gcm.go +++ b/src/crypto/cipher/gcm.go @@ -80,7 +80,7 @@ type gcm struct { // An exception is when the underlying Block was created by aes.NewCipher // on systems with hardware support for AES. See the crypto/aes package documentation for details. func NewGCM(cipher Block) (AEAD, error) { - return NewGCMWithNonceAndTagSize(cipher, gcmStandardNonceSize, gcmTagSize) + return newGCMWithNonceAndTagSize(cipher, gcmStandardNonceSize, gcmTagSize) } // NewGCMWithNonceSize returns the given 128-bit, block cipher wrapped in Galois @@ -90,18 +90,22 @@ func NewGCM(cipher Block) (AEAD, error) { // cryptosystem that uses non-standard nonce lengths. All other users should use // NewGCM, which is faster and more resistant to misuse. func NewGCMWithNonceSize(cipher Block, size int) (AEAD, error) { - return NewGCMWithNonceAndTagSize(cipher, size, gcmTagSize) + return newGCMWithNonceAndTagSize(cipher, size, gcmTagSize) } -// NewGCMWithNonceAndTagSize returns the given 128-bit, block cipher wrapped in Galois -// Counter Mode, which accepts nonces of the given length and generates tags with the given length. +// NewGCMWithTagSize returns the given 128-bit, block cipher wrapped in Galois +// Counter Mode, which generates tags with the given length. // // Tag sizes between 12 and 16 bytes are allowed. // // Only use this function if you require compatibility with an existing // cryptosystem that uses non-standard tag lengths. All other users should use // NewGCM, which is more resistant to misuse. -func NewGCMWithNonceAndTagSize(cipher Block, nonceSize, tagSize int) (AEAD, error) { +func NewGCMWithTagSize(cipher Block, tagSize int) (AEAD, error) { + return newGCMWithNonceAndTagSize(cipher, gcmStandardNonceSize, tagSize) +} + +func newGCMWithNonceAndTagSize(cipher Block, nonceSize, tagSize int) (AEAD, error) { if tagSize < gcmMinimumTagSize || tagSize > gcmBlockSize { return nil, errors.New("cipher: incorrect tag size given to GCM") } diff --git a/src/crypto/cipher/gcm_test.go b/src/crypto/cipher/gcm_test.go index 31f4d95364..c48001db28 100644 --- a/src/crypto/cipher/gcm_test.go +++ b/src/crypto/cipher/gcm_test.go @@ -231,9 +231,28 @@ func TestAESGCM(t *testing.T) { plaintext, _ := hex.DecodeString(test.plaintext) ad, _ := hex.DecodeString(test.ad) tagSize := (len(test.result) - len(test.plaintext)) / 2 - aesgcm, err := cipher.NewGCMWithNonceAndTagSize(aes, len(nonce), tagSize) - if err != nil { - t.Fatal(err) + + var aesgcm cipher.AEAD + switch { + // Handle non-standard nonce sizes + case tagSize != 16: + aesgcm, err = cipher.NewGCMWithTagSize(aes, tagSize) + if err != nil { + t.Fatal(err) + } + + // Handle non-standard tag sizes + case len(nonce) != 12: + aesgcm, err = cipher.NewGCMWithNonceSize(aes, len(nonce)) + if err != nil { + t.Fatal(err) + } + + default: + aesgcm, err = cipher.NewGCM(aes) + if err != nil { + t.Fatal(err) + } } ct := aesgcm.Seal(nil, nonce, plaintext, ad) @@ -277,12 +296,11 @@ func TestAESGCM(t *testing.T) { func TestGCMInvalidTagSize(t *testing.T) { key, _ := hex.DecodeString("ab72c77b97cb5fe9a382d9fe81ffdbed") - nonce, _ := hex.DecodeString("54cc7dc2c37ec006bcc6d1db") aes, _ := aes.NewCipher(key) for _, tagSize := range []int{0, 1, aes.BlockSize() + 1} { - aesgcm, err := cipher.NewGCMWithNonceAndTagSize(aes, len(nonce), tagSize) + aesgcm, err := cipher.NewGCMWithTagSize(aes, tagSize) if aesgcm != nil || err == nil { t.Fatalf("NewGCMWithNonceAndTagSize was successful with an invalid %d-byte tag size", tagSize) }