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