// 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
// 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")
}
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)
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)
}