Source file src/crypto/cipher/cbc_aes_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  	"crypto/aes"
     8  	"crypto/cipher"
     9  	"crypto/internal/cryptotest"
    10  	"crypto/internal/cryptotest/wycheproof"
    11  	"encoding/hex"
    12  	"testing"
    13  )
    14  
    15  func TestCBCAESWycheproof(t *testing.T) {
    16  	cryptotest.TestAllImplementations(t, "aes", func(t *testing.T) {
    17  		file := "aes_cbc_pkcs5_test.json"
    18  		var testdata wycheproof.IndCpaTestSchemaV1Json
    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  					block, err := aes.NewCipher(wycheproof.MustDecodeHex(tv.Key))
    27  					if err != nil {
    28  						t.Fatalf("NewCipher: %v", err)
    29  					}
    30  					mode := cipher.NewCBCDecrypter(block, wycheproof.MustDecodeHex(tv.Iv))
    31  					ct := wycheproof.MustDecodeHex(tv.Ct)
    32  					if len(ct)%aes.BlockSize != 0 {
    33  						t.Fatalf("ciphertext is not a multiple of the block size")
    34  					}
    35  					mode.CryptBlocks(ct, ct) // decrypt the block in place
    36  
    37  					// Test cases with bad/missing padding are expected to fail,
    38  					// but cipher.CBCDecrypter doesn't validate padding. Skip these.
    39  					// Fail loudly if there's an invalid test for any other reason,
    40  					// so we can evaluate what to do with it.
    41  					for _, flag := range tv.Flags {
    42  						if flag == "BadPadding" || flag == "NoPadding" {
    43  							return
    44  						}
    45  					}
    46  					if !wycheproof.ShouldPass(t, tv.Result, tv.Flags, nil) {
    47  						t.Fatalf("unexpected invalid test (not BadPadding/NoPadding)")
    48  					}
    49  
    50  					// Remove the PKCS#5 padding from the given ciphertext to validate it
    51  					padding := ct[len(ct)-1]
    52  					paddingNum := int(padding)
    53  					for i := paddingNum; i > 0; i-- {
    54  						if ct[len(ct)-i] != padding { // panic if the padding is unexpectedly bad
    55  							t.Fatalf("bad padding at index=%d of %v", i, ct)
    56  						}
    57  					}
    58  					ct = ct[:len(ct)-paddingNum]
    59  
    60  					if got, want := hex.EncodeToString(ct), tv.Msg; got != want {
    61  						t.Errorf("decoded ciphertext not equal: %s, want %s", got, want)
    62  					}
    63  				})
    64  			}
    65  		}
    66  	})
    67  }
    68  

View as plain text