Source file src/crypto/cipher/gcm_wycheproof_test.go

     1  // Copyright 2026 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  package cipher_test
     5  
     6  import (
     7  	"bytes"
     8  	"crypto/aes"
     9  	"crypto/cipher"
    10  	"crypto/internal/cryptotest"
    11  	"crypto/internal/cryptotest/wycheproof"
    12  	"testing"
    13  )
    14  
    15  func TestGCMWycheproof(t *testing.T) {
    16  	cryptotest.TestAllImplementations(t, "gcm", func(t *testing.T) {
    17  		file := "aes_gcm_test.json"
    18  		var testdata wycheproof.AeadTestSchemaV1Json
    19  		wycheproof.LoadVectorFile(t, file, &testdata)
    20  
    21  		for _, tg := range testdata.TestGroups {
    22  			for _, tv := range tg.Tests {
    23  				t.Run(wycheproof.TestName(file, tv), func(t *testing.T) {
    24  					t.Parallel()
    25  
    26  					aesCipher, err := aes.NewCipher(wycheproof.MustDecodeHex(tv.Key))
    27  					if err != nil {
    28  						t.Fatalf("failed to construct cipher: %s", err)
    29  					}
    30  					aead, err := cipher.NewGCM(aesCipher)
    31  					if err != nil {
    32  						t.Fatalf("failed to construct cipher: %s", err)
    33  					}
    34  
    35  					iv := wycheproof.MustDecodeHex(tv.Iv)
    36  					tag := wycheproof.MustDecodeHex(tv.Tag)
    37  					ct := wycheproof.MustDecodeHex(tv.Ct)
    38  					msg := wycheproof.MustDecodeHex(tv.Msg)
    39  					aad := wycheproof.MustDecodeHex(tv.Aad)
    40  
    41  					// The Go implementation panics on invalid nonce sizes rather
    42  					// than returning an error. Verify this behavior.
    43  					if len(iv) != aead.NonceSize() {
    44  						ctWithTag := append(ct, tag...)
    45  						wycheproof.MustPanic(t, "Seal", func() { aead.Seal(nil, iv, msg, aad) })
    46  						wycheproof.MustPanic(t, "Open", func() { aead.Open(nil, iv, ctWithTag, aad) })
    47  						return
    48  					}
    49  
    50  					genCT := aead.Seal(nil, iv, msg, aad)
    51  					genMsg, err := aead.Open(nil, iv, genCT, aad)
    52  					if err != nil {
    53  						t.Errorf("failed to decrypt generated ciphertext: %s", err)
    54  					}
    55  					if !bytes.Equal(genMsg, msg) {
    56  						t.Errorf("unexpected roundtripped plaintext: got %x, want %x", genMsg, msg)
    57  					}
    58  
    59  					ctWithTag := append(ct, tag...)
    60  					msg2, err := aead.Open(nil, iv, ctWithTag, aad)
    61  					wantPass := wycheproof.ShouldPass(t, tv.Result, tv.Flags, nil)
    62  					if !wantPass && err == nil {
    63  						t.Error("decryption succeeded when it should've failed")
    64  					} else if wantPass {
    65  						if err != nil {
    66  							t.Fatalf("decryption failed: %s", err)
    67  						}
    68  						if !bytes.Equal(genCT, ctWithTag) {
    69  							t.Errorf("generated ciphertext doesn't match expected: got %x, want %x", genCT, ctWithTag)
    70  						}
    71  						if !bytes.Equal(msg, msg2) {
    72  							t.Errorf("decrypted ciphertext doesn't match expected: got %x, want %x", msg2, msg)
    73  						}
    74  					}
    75  				})
    76  			}
    77  		}
    78  	})
    79  }
    80  

View as plain text