| // Copyright 2026 The Go Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style |
| // license that can be found in the LICENSE file. |
| package cipher_test |
| |
| import ( |
| "crypto/aes" |
| "crypto/cipher" |
| "crypto/internal/cryptotest" |
| "crypto/internal/cryptotest/wycheproof" |
| "encoding/hex" |
| "testing" |
| ) |
| |
| func TestCBCAESWycheproof(t *testing.T) { |
| cryptotest.TestAllImplementations(t, "aes", func(t *testing.T) { |
| file := "aes_cbc_pkcs5_test.json" |
| var testdata wycheproof.IndCpaTestSchemaV1Json |
| wycheproof.LoadVectorFile(t, file, &testdata) |
| |
| for _, tg := range testdata.TestGroups { |
| for _, tv := range tg.Tests { |
| t.Run(wycheproof.TestName(file, tv), func(t *testing.T) { |
| t.Parallel() |
| |
| block, err := aes.NewCipher(wycheproof.MustDecodeHex(tv.Key)) |
| if err != nil { |
| t.Fatalf("NewCipher: %v", err) |
| } |
| mode := cipher.NewCBCDecrypter(block, wycheproof.MustDecodeHex(tv.Iv)) |
| ct := wycheproof.MustDecodeHex(tv.Ct) |
| if len(ct)%aes.BlockSize != 0 { |
| t.Fatalf("ciphertext is not a multiple of the block size") |
| } |
| mode.CryptBlocks(ct, ct) // decrypt the block in place |
| |
| // Test cases with bad/missing padding are expected to fail, |
| // but cipher.CBCDecrypter doesn't validate padding. Skip these. |
| // Fail loudly if there's an invalid test for any other reason, |
| // so we can evaluate what to do with it. |
| for _, flag := range tv.Flags { |
| if flag == "BadPadding" || flag == "NoPadding" { |
| return |
| } |
| } |
| if !wycheproof.ShouldPass(t, tv.Result, tv.Flags, nil) { |
| t.Fatalf("unexpected invalid test (not BadPadding/NoPadding)") |
| } |
| |
| // Remove the PKCS#5 padding from the given ciphertext to validate it |
| padding := ct[len(ct)-1] |
| paddingNum := int(padding) |
| for i := paddingNum; i > 0; i-- { |
| if ct[len(ct)-i] != padding { // panic if the padding is unexpectedly bad |
| t.Fatalf("bad padding at index=%d of %v", i, ct) |
| } |
| } |
| ct = ct[:len(ct)-paddingNum] |
| |
| if got, want := hex.EncodeToString(ct), tv.Msg; got != want { |
| t.Errorf("decoded ciphertext not equal: %s, want %s", got, want) |
| } |
| }) |
| } |
| } |
| }) |
| } |