xref: /aosp_15_r20/external/tink/go/kwp/subtle/kwp_test.go (revision e7b1675dde1b92d52ec075b0a92829627f2c52a5)
1*e7b1675dSTing-Kang Chang// Copyright 2020 Google LLC
2*e7b1675dSTing-Kang Chang//
3*e7b1675dSTing-Kang Chang// Licensed under the Apache License, Version 2.0 (the "License");
4*e7b1675dSTing-Kang Chang// you may not use this file except in compliance with the License.
5*e7b1675dSTing-Kang Chang// You may obtain a copy of the License at
6*e7b1675dSTing-Kang Chang//
7*e7b1675dSTing-Kang Chang//      http://www.apache.org/licenses/LICENSE-2.0
8*e7b1675dSTing-Kang Chang//
9*e7b1675dSTing-Kang Chang// Unless required by applicable law or agreed to in writing, software
10*e7b1675dSTing-Kang Chang// distributed under the License is distributed on an "AS IS" BASIS,
11*e7b1675dSTing-Kang Chang// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*e7b1675dSTing-Kang Chang// See the License for the specific language governing permissions and
13*e7b1675dSTing-Kang Chang// limitations under the License.
14*e7b1675dSTing-Kang Chang//
15*e7b1675dSTing-Kang Chang////////////////////////////////////////////////////////////////////////////////
16*e7b1675dSTing-Kang Chang
17*e7b1675dSTing-Kang Changpackage subtle_test
18*e7b1675dSTing-Kang Chang
19*e7b1675dSTing-Kang Changimport (
20*e7b1675dSTing-Kang Chang	"bytes"
21*e7b1675dSTing-Kang Chang	"encoding/hex"
22*e7b1675dSTing-Kang Chang	"encoding/json"
23*e7b1675dSTing-Kang Chang	"fmt"
24*e7b1675dSTing-Kang Chang	"os"
25*e7b1675dSTing-Kang Chang	"path/filepath"
26*e7b1675dSTing-Kang Chang	"testing"
27*e7b1675dSTing-Kang Chang
28*e7b1675dSTing-Kang Chang	"github.com/google/tink/go/kwp/subtle"
29*e7b1675dSTing-Kang Chang	"github.com/google/tink/go/subtle/random"
30*e7b1675dSTing-Kang Chang	"github.com/google/tink/go/testutil"
31*e7b1675dSTing-Kang Chang)
32*e7b1675dSTing-Kang Chang
33*e7b1675dSTing-Kang Changfunc TestWrapUnwrap(t *testing.T) {
34*e7b1675dSTing-Kang Chang	kek := random.GetRandomBytes(16)
35*e7b1675dSTing-Kang Chang	cipher, err := subtle.NewKWP(kek)
36*e7b1675dSTing-Kang Chang	if err != nil {
37*e7b1675dSTing-Kang Chang		t.Fatalf("failed to make kwp, error: %v", err)
38*e7b1675dSTing-Kang Chang	}
39*e7b1675dSTing-Kang Chang
40*e7b1675dSTing-Kang Chang	for i := uint32(16); i < 128; i++ {
41*e7b1675dSTing-Kang Chang		t.Run(fmt.Sprintf("MessageSize%d", i), func(t *testing.T) {
42*e7b1675dSTing-Kang Chang			toWrap := random.GetRandomBytes(i)
43*e7b1675dSTing-Kang Chang
44*e7b1675dSTing-Kang Chang			wrapped, err := cipher.Wrap(toWrap)
45*e7b1675dSTing-Kang Chang			if err != nil {
46*e7b1675dSTing-Kang Chang				t.Fatalf("failed to wrap, error: %v", err)
47*e7b1675dSTing-Kang Chang			}
48*e7b1675dSTing-Kang Chang
49*e7b1675dSTing-Kang Chang			unwrapped, err := cipher.Unwrap(wrapped)
50*e7b1675dSTing-Kang Chang			if err != nil {
51*e7b1675dSTing-Kang Chang				t.Fatalf("failed to unwrap, error: %v", err)
52*e7b1675dSTing-Kang Chang			}
53*e7b1675dSTing-Kang Chang
54*e7b1675dSTing-Kang Chang			if !bytes.Equal(toWrap, unwrapped) {
55*e7b1675dSTing-Kang Chang				t.Error("unwrapped doesn't match original key")
56*e7b1675dSTing-Kang Chang			}
57*e7b1675dSTing-Kang Chang		})
58*e7b1675dSTing-Kang Chang	}
59*e7b1675dSTing-Kang Chang}
60*e7b1675dSTing-Kang Chang
61*e7b1675dSTing-Kang Changfunc TestKeySizes(t *testing.T) {
62*e7b1675dSTing-Kang Chang	for i := 0; i < 255; i++ {
63*e7b1675dSTing-Kang Chang		expectSuccess := i == 16 || i == 32
64*e7b1675dSTing-Kang Chang		t.Run(fmt.Sprintf("KeySize%d", i), func(t *testing.T) {
65*e7b1675dSTing-Kang Chang			_, err := subtle.NewKWP(make([]byte, i))
66*e7b1675dSTing-Kang Chang
67*e7b1675dSTing-Kang Chang			if expectSuccess && err != nil {
68*e7b1675dSTing-Kang Chang				t.Errorf("failed to create KWP: %v", err)
69*e7b1675dSTing-Kang Chang			}
70*e7b1675dSTing-Kang Chang
71*e7b1675dSTing-Kang Chang			if !expectSuccess && err == nil {
72*e7b1675dSTing-Kang Chang				t.Error("created KWP with invalid key size")
73*e7b1675dSTing-Kang Chang			}
74*e7b1675dSTing-Kang Chang		})
75*e7b1675dSTing-Kang Chang
76*e7b1675dSTing-Kang Chang	}
77*e7b1675dSTing-Kang Chang}
78*e7b1675dSTing-Kang Chang
79*e7b1675dSTing-Kang Changfunc TestInvalidWrappingSizes(t *testing.T) {
80*e7b1675dSTing-Kang Chang	kek := random.GetRandomBytes(16)
81*e7b1675dSTing-Kang Chang	cipher, err := subtle.NewKWP(kek)
82*e7b1675dSTing-Kang Chang	if err != nil {
83*e7b1675dSTing-Kang Chang		t.Fatalf("failed to make kwp, error: %v", err)
84*e7b1675dSTing-Kang Chang	}
85*e7b1675dSTing-Kang Chang
86*e7b1675dSTing-Kang Chang	for i := 0; i < 16; i++ {
87*e7b1675dSTing-Kang Chang		t.Run(fmt.Sprintf("KeySize%d", i), func(t *testing.T) {
88*e7b1675dSTing-Kang Chang			if _, err := cipher.Wrap(make([]byte, i)); err == nil {
89*e7b1675dSTing-Kang Chang				t.Error("wrapped a short key")
90*e7b1675dSTing-Kang Chang			}
91*e7b1675dSTing-Kang Chang		})
92*e7b1675dSTing-Kang Chang	}
93*e7b1675dSTing-Kang Chang}
94*e7b1675dSTing-Kang Chang
95*e7b1675dSTing-Kang Changtype KwpCase struct {
96*e7b1675dSTing-Kang Chang	testutil.WycheproofCase
97*e7b1675dSTing-Kang Chang	Key        string `json:"key"`
98*e7b1675dSTing-Kang Chang	Message    string `json:"msg"`
99*e7b1675dSTing-Kang Chang	Ciphertext string `json:"ct"`
100*e7b1675dSTing-Kang Chang}
101*e7b1675dSTing-Kang Chang
102*e7b1675dSTing-Kang Changtype KwpGroup struct {
103*e7b1675dSTing-Kang Chang	testutil.WycheproofGroup
104*e7b1675dSTing-Kang Chang	KeySize int        `json:"keySize"`
105*e7b1675dSTing-Kang Chang	Tests   []*KwpCase `json:"tests"`
106*e7b1675dSTing-Kang Chang}
107*e7b1675dSTing-Kang Chang
108*e7b1675dSTing-Kang Changtype KwpSuite struct {
109*e7b1675dSTing-Kang Chang	testutil.WycheproofSuite
110*e7b1675dSTing-Kang Chang	Groups []*KwpGroup `json:"testGroups"`
111*e7b1675dSTing-Kang Chang}
112*e7b1675dSTing-Kang Chang
113*e7b1675dSTing-Kang Changfunc TestWycheproofCases(t *testing.T) {
114*e7b1675dSTing-Kang Chang	srcDir, ok := os.LookupEnv("TEST_SRCDIR")
115*e7b1675dSTing-Kang Chang	if !ok {
116*e7b1675dSTing-Kang Chang		t.Skip("TEST_SRCDIR not set")
117*e7b1675dSTing-Kang Chang	}
118*e7b1675dSTing-Kang Chang	f, err := os.Open(filepath.Join(srcDir, "wycheproof/testvectors/kwp_test.json"))
119*e7b1675dSTing-Kang Chang	if err != nil {
120*e7b1675dSTing-Kang Chang		t.Fatalf("cannot open file %s", err)
121*e7b1675dSTing-Kang Chang	}
122*e7b1675dSTing-Kang Chang	parser := json.NewDecoder(f)
123*e7b1675dSTing-Kang Chang	suite := new(KwpSuite)
124*e7b1675dSTing-Kang Chang	if err := parser.Decode(suite); err != nil {
125*e7b1675dSTing-Kang Chang		t.Fatalf("cannot decode test data: %s", err)
126*e7b1675dSTing-Kang Chang	}
127*e7b1675dSTing-Kang Chang
128*e7b1675dSTing-Kang Chang	for _, group := range suite.Groups {
129*e7b1675dSTing-Kang Chang		if group.KeySize == 192 {
130*e7b1675dSTing-Kang Chang			continue
131*e7b1675dSTing-Kang Chang		}
132*e7b1675dSTing-Kang Chang
133*e7b1675dSTing-Kang Chang		for _, test := range group.Tests {
134*e7b1675dSTing-Kang Chang			caseName := fmt.Sprintf("%s-%s(%d):Case-%d",
135*e7b1675dSTing-Kang Chang				suite.Algorithm, group.Type, group.KeySize, test.CaseID)
136*e7b1675dSTing-Kang Chang			t.Run(caseName, func(t *testing.T) { runWycheproofCase(t, test) })
137*e7b1675dSTing-Kang Chang		}
138*e7b1675dSTing-Kang Chang	}
139*e7b1675dSTing-Kang Chang}
140*e7b1675dSTing-Kang Chang
141*e7b1675dSTing-Kang Changfunc runWycheproofCase(t *testing.T, testCase *KwpCase) {
142*e7b1675dSTing-Kang Chang	kek, err := hex.DecodeString(testCase.Key)
143*e7b1675dSTing-Kang Chang	if err != nil {
144*e7b1675dSTing-Kang Chang		t.Fatalf("hex.DecodeString(testCase.Key) => %v", err)
145*e7b1675dSTing-Kang Chang	}
146*e7b1675dSTing-Kang Chang
147*e7b1675dSTing-Kang Chang	msg, err := hex.DecodeString(testCase.Message)
148*e7b1675dSTing-Kang Chang	if err != nil {
149*e7b1675dSTing-Kang Chang		t.Fatalf("hex.DecodeString(testCase.Message) => %v", err)
150*e7b1675dSTing-Kang Chang	}
151*e7b1675dSTing-Kang Chang
152*e7b1675dSTing-Kang Chang	ct, err := hex.DecodeString(testCase.Ciphertext)
153*e7b1675dSTing-Kang Chang	if err != nil {
154*e7b1675dSTing-Kang Chang		t.Fatalf("hex.DecodeString(testCase.Ciphertext) => %v", err)
155*e7b1675dSTing-Kang Chang	}
156*e7b1675dSTing-Kang Chang
157*e7b1675dSTing-Kang Chang	cipher, err := subtle.NewKWP(kek)
158*e7b1675dSTing-Kang Chang	if err != nil {
159*e7b1675dSTing-Kang Chang		switch testCase.Result {
160*e7b1675dSTing-Kang Chang		case "valid":
161*e7b1675dSTing-Kang Chang			t.Fatalf("cannot create kwp, error: %v", err)
162*e7b1675dSTing-Kang Chang		case "invalid", "acceptable":
163*e7b1675dSTing-Kang Chang			return
164*e7b1675dSTing-Kang Chang		}
165*e7b1675dSTing-Kang Chang	}
166*e7b1675dSTing-Kang Chang
167*e7b1675dSTing-Kang Chang	wrapped, err := cipher.Wrap(msg)
168*e7b1675dSTing-Kang Chang	switch testCase.Result {
169*e7b1675dSTing-Kang Chang	case "valid":
170*e7b1675dSTing-Kang Chang		if err != nil {
171*e7b1675dSTing-Kang Chang			t.Errorf("cannot wrap, error: %v", err)
172*e7b1675dSTing-Kang Chang		} else if !bytes.Equal(ct, wrapped) {
173*e7b1675dSTing-Kang Chang			t.Error("wrapped key mismatches test vector")
174*e7b1675dSTing-Kang Chang		}
175*e7b1675dSTing-Kang Chang	case "invalid":
176*e7b1675dSTing-Kang Chang		if err == nil && bytes.Equal(ct, wrapped) {
177*e7b1675dSTing-Kang Chang			t.Error("no error and wrapped key matches test vector for invalid case")
178*e7b1675dSTing-Kang Chang		}
179*e7b1675dSTing-Kang Chang	case "acceptable":
180*e7b1675dSTing-Kang Chang		if err == nil && !bytes.Equal(ct, wrapped) {
181*e7b1675dSTing-Kang Chang			t.Error("no error and wrapped key mismatches test vector for acceptable case")
182*e7b1675dSTing-Kang Chang		}
183*e7b1675dSTing-Kang Chang	}
184*e7b1675dSTing-Kang Chang
185*e7b1675dSTing-Kang Chang	unwrapped, err := cipher.Unwrap(ct)
186*e7b1675dSTing-Kang Chang	switch testCase.Result {
187*e7b1675dSTing-Kang Chang	case "valid":
188*e7b1675dSTing-Kang Chang		if err != nil {
189*e7b1675dSTing-Kang Chang			t.Errorf("cannot unwrap, error: %v", err)
190*e7b1675dSTing-Kang Chang		} else if !bytes.Equal(msg, unwrapped) {
191*e7b1675dSTing-Kang Chang			t.Error("unwrapped key mismatches test vector")
192*e7b1675dSTing-Kang Chang		}
193*e7b1675dSTing-Kang Chang	case "invalid":
194*e7b1675dSTing-Kang Chang		if err == nil {
195*e7b1675dSTing-Kang Chang			t.Error("no error unwrapping invalid case")
196*e7b1675dSTing-Kang Chang		}
197*e7b1675dSTing-Kang Chang	case "acceptable":
198*e7b1675dSTing-Kang Chang		if err == nil && !bytes.Equal(msg, unwrapped) {
199*e7b1675dSTing-Kang Chang			t.Error("no error and unwrapped key mismatches plaintext")
200*e7b1675dSTing-Kang Chang		}
201*e7b1675dSTing-Kang Chang	}
202*e7b1675dSTing-Kang Chang}
203