Skip to content

Commit 1ad67e1

Browse files
committed
internal/wycheproof: add test for CBC decryption with PKCS#5 padding
Change-Id: Ie60bdc10065018e193271b4f90f50298f1272396 Reviewed-on: https://go-review.googlesource.com/c/crypto/+/218323 Run-TryBot: Katie Hockman <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Filippo Valsorda <[email protected]>
1 parent 1d94cc7 commit 1ad67e1

File tree

1 file changed

+127
-0
lines changed

1 file changed

+127
-0
lines changed

internal/wycheproof/aes_cbc_test.go

+127
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
// Copyright 2019 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+
5+
package wycheproof
6+
7+
import (
8+
"crypto/aes"
9+
"crypto/cipher"
10+
"encoding/hex"
11+
"fmt"
12+
"testing"
13+
)
14+
15+
func TestAesCbc(t *testing.T) {
16+
// IndCpaTestVector
17+
type IndCpaTestVector struct {
18+
19+
// A brief description of the test case
20+
Comment string `json:"comment,omitempty"`
21+
22+
// the raw ciphertext (without IV)
23+
Ct string `json:"ct,omitempty"`
24+
25+
// A list of flags
26+
Flags []string `json:"flags,omitempty"`
27+
28+
// the initialization vector
29+
Iv string `json:"iv,omitempty"`
30+
31+
// the key
32+
Key string `json:"key,omitempty"`
33+
34+
// the plaintext
35+
Msg string `json:"msg,omitempty"`
36+
37+
// Test result
38+
Result string `json:"result,omitempty"`
39+
40+
// Identifier of the test case
41+
TcId int `json:"tcId,omitempty"`
42+
}
43+
44+
// Notes a description of the labels used in the test vectors
45+
type Notes struct {
46+
}
47+
48+
// IndCpaTestGroup
49+
type IndCpaTestGroup struct {
50+
51+
// the IV size in bits
52+
IvSize int `json:"ivSize,omitempty"`
53+
54+
// the keySize in bits
55+
KeySize int `json:"keySize,omitempty"`
56+
57+
// the expected size of the tag in bits
58+
TagSize int `json:"tagSize,omitempty"`
59+
Tests []*IndCpaTestVector `json:"tests,omitempty"`
60+
Type interface{} `json:"type,omitempty"`
61+
}
62+
63+
// Root
64+
type Root struct {
65+
66+
// the primitive tested in the test file
67+
Algorithm string `json:"algorithm,omitempty"`
68+
69+
// the version of the test vectors.
70+
GeneratorVersion string `json:"generatorVersion,omitempty"`
71+
72+
// additional documentation
73+
Header []string `json:"header,omitempty"`
74+
75+
// a description of the labels used in the test vectors
76+
Notes *Notes `json:"notes,omitempty"`
77+
78+
// the number of test vectors in this test
79+
NumberOfTests int `json:"numberOfTests,omitempty"`
80+
Schema interface{} `json:"schema,omitempty"`
81+
TestGroups []*IndCpaTestGroup `json:"testGroups,omitempty"`
82+
}
83+
84+
var root Root
85+
readTestVector(t, "aes_cbc_pkcs5_test.json", &root)
86+
for _, tg := range root.TestGroups {
87+
tests:
88+
for _, tv := range tg.Tests {
89+
block, err := aes.NewCipher(decodeHex(tv.Key))
90+
if err != nil {
91+
t.Fatalf("#%d: %v", tv.TcId, err)
92+
}
93+
mode := cipher.NewCBCDecrypter(block, decodeHex(tv.Iv))
94+
ct := decodeHex(tv.Ct)
95+
if len(ct)%aes.BlockSize != 0 {
96+
panic(fmt.Sprintf("#%d: ciphertext is not a multiple of the block size", tv.TcId))
97+
}
98+
mode.CryptBlocks(ct, ct) // decrypt the block in place
99+
100+
// Skip the tests that are broken due to bad padding. Panic if there are any
101+
// tests left that are invalid for some other reason in the future, to
102+
// evaluate what to do with those tests.
103+
for _, flag := range tv.Flags {
104+
if flag == "BadPadding" {
105+
continue tests
106+
}
107+
}
108+
if !shouldPass(tv.Result, tv.Flags, nil) {
109+
panic(fmt.Sprintf("#%d: found an invalid test that is broken for some reason other than bad padding", tv.TcId))
110+
}
111+
112+
// Remove the PKCS#5 padding from the given ciphertext to validate it
113+
padding := ct[len(ct)-1]
114+
paddingNum := int(padding)
115+
for i := paddingNum; i > 0; i-- {
116+
if ct[len(ct)-i] != padding { // panic if the padding is unexpectedly bad
117+
panic(fmt.Sprintf("#%d: bad padding at index=%d of %v", tv.TcId, i, ct))
118+
}
119+
}
120+
ct = ct[:len(ct)-paddingNum]
121+
122+
if got, want := hex.EncodeToString(ct), tv.Msg; got != want {
123+
t.Errorf("#%d, type: %s, comment: %q, decoded ciphertext not equal: %s, want %s", tv.TcId, tv.Result, tv.Comment, got, want)
124+
}
125+
}
126+
}
127+
}

0 commit comments

Comments
 (0)