xref: /aosp_15_r20/external/tink/go/daead/aes_siv_key_manager_test.go (revision e7b1675dde1b92d52ec075b0a92829627f2c52a5)
1// Copyright 2019 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 daead_test
18
19import (
20	"bytes"
21	"encoding/hex"
22	"fmt"
23	"testing"
24
25	"github.com/google/go-cmp/cmp"
26	"google.golang.org/protobuf/proto"
27	"github.com/google/tink/go/core/registry"
28	"github.com/google/tink/go/internal/internalregistry"
29	"github.com/google/tink/go/subtle/random"
30	"github.com/google/tink/go/testutil"
31
32	"github.com/google/tink/go/daead/subtle"
33	aspb "github.com/google/tink/go/proto/aes_siv_go_proto"
34	tpb "github.com/google/tink/go/proto/tink_go_proto"
35)
36
37func TestAESSIVPrimitive(t *testing.T) {
38	km, err := registry.GetKeyManager(testutil.AESSIVTypeURL)
39	if err != nil {
40		t.Fatalf("cannot obtain AESSIV key manager: %s", err)
41	}
42	m, err := km.NewKey(nil)
43	if err != nil {
44		t.Errorf("km.NewKey(nil) = _, %v; want _, nil", err)
45	}
46	key, _ := m.(*aspb.AesSivKey)
47	serializedKey, _ := proto.Marshal(key)
48	p, err := km.Primitive(serializedKey)
49	if err != nil {
50		t.Errorf("km.Primitive(%v) = %v; want nil", serializedKey, err)
51	}
52	if err := validateAESSIVPrimitive(p, key); err != nil {
53		t.Errorf("validateAESSIVPrimitive(p, key) = %v; want nil", err)
54	}
55}
56
57func TestAESSIVPrimitiveWithInvalidKeys(t *testing.T) {
58	km, err := registry.GetKeyManager(testutil.AESSIVTypeURL)
59	if err != nil {
60		t.Errorf("cannot obtain AESSIV key manager: %s", err)
61	}
62	invalidKeys := []*aspb.AesSivKey{
63		// Bad key size.
64		&aspb.AesSivKey{
65			Version:  testutil.AESSIVKeyVersion,
66			KeyValue: random.GetRandomBytes(16),
67		},
68		&aspb.AesSivKey{
69			Version:  testutil.AESSIVKeyVersion,
70			KeyValue: random.GetRandomBytes(32),
71		},
72		&aspb.AesSivKey{
73			Version:  testutil.AESSIVKeyVersion,
74			KeyValue: random.GetRandomBytes(63),
75		},
76		&aspb.AesSivKey{
77			Version:  testutil.AESSIVKeyVersion,
78			KeyValue: random.GetRandomBytes(65),
79		},
80		// Bad version.
81		&aspb.AesSivKey{
82			Version:  testutil.AESSIVKeyVersion + 1,
83			KeyValue: random.GetRandomBytes(subtle.AESSIVKeySize),
84		},
85	}
86	for _, key := range invalidKeys {
87		serializedKey, _ := proto.Marshal(key)
88		if _, err := km.Primitive(serializedKey); err == nil {
89			t.Errorf("km.Primitive(%v) = _, nil; want _, err", serializedKey)
90		}
91	}
92}
93
94func TestAESSIVNewKey(t *testing.T) {
95	km, err := registry.GetKeyManager(testutil.AESSIVTypeURL)
96	if err != nil {
97		t.Errorf("cannot obtain AESSIV key manager: %s", err)
98	}
99	m, err := km.NewKey(nil)
100	if err != nil {
101		t.Errorf("km.NewKey(nil) = _, %v; want _, nil", err)
102	}
103	key, _ := m.(*aspb.AesSivKey)
104	if err := validateAESSIVKey(key); err != nil {
105		t.Errorf("validateAESSIVKey(%v) = %v; want nil", key, err)
106	}
107}
108
109func TestAESSIVNewKeyData(t *testing.T) {
110	km, err := registry.GetKeyManager(testutil.AESSIVTypeURL)
111	if err != nil {
112		t.Errorf("cannot obtain AESSIV key manager: %s", err)
113	}
114	kd, err := km.NewKeyData(nil)
115	if err != nil {
116		t.Errorf("km.NewKeyData(nil) = _, %v; want _, nil", err)
117	}
118	if kd.TypeUrl != testutil.AESSIVTypeURL {
119		t.Errorf("TypeUrl: %v != %v", kd.TypeUrl, testutil.AESSIVTypeURL)
120	}
121	if kd.KeyMaterialType != tpb.KeyData_SYMMETRIC {
122		t.Errorf("KeyMaterialType: %v != SYMMETRIC", kd.KeyMaterialType)
123	}
124	key := new(aspb.AesSivKey)
125	if err := proto.Unmarshal(kd.Value, key); err != nil {
126		t.Errorf("proto.Unmarshal(%v, key) = %v; want nil", kd.Value, err)
127	}
128	if err := validateAESSIVKey(key); err != nil {
129		t.Errorf("validateAESSIVKey(%v) = %v; want nil", key, err)
130	}
131}
132
133func TestAESSIVNewKeyInvalid(t *testing.T) {
134	km, err := registry.GetKeyManager(testutil.AESSIVTypeURL)
135	if err != nil {
136		t.Errorf("registry.GetKeyManager(%q) err = %v, want nil", testutil.AESSIVTypeURL, err)
137	}
138	invalidKeySize, err := proto.Marshal(&aspb.AesSivKeyFormat{
139		KeySize: subtle.AESSIVKeySize - 1,
140		Version: testutil.AESSIVKeyVersion,
141	})
142	if err != nil {
143		t.Errorf("proto.Marshal() err = %v, want nil", err)
144	}
145	// Proto messages start with a VarInt, which always ends with a byte with the
146	// MSB unset, so 0x80 is invalid.
147	invalidSerialization, err := hex.DecodeString("80")
148	if err != nil {
149		t.Errorf("hex.DecodeString() err = %v, want nil", err)
150	}
151	for _, test := range []struct {
152		name      string
153		keyFormat []byte
154	}{
155		{
156			name:      "invalid key size",
157			keyFormat: invalidKeySize,
158		},
159		{
160			name:      "invalid serialization",
161			keyFormat: invalidSerialization,
162		},
163	} {
164		t.Run(test.name, func(t *testing.T) {
165			if _, err = km.NewKey(test.keyFormat); err == nil {
166				t.Error("km.NewKey() err = nil, want non-nil")
167			}
168		})
169	}
170}
171
172func TestAESSIVDoesSupport(t *testing.T) {
173	km, err := registry.GetKeyManager(testutil.AESSIVTypeURL)
174	if err != nil {
175		t.Errorf("cannot obtain AESSIV key manager: %s", err)
176	}
177	if !km.DoesSupport(testutil.AESSIVTypeURL) {
178		t.Errorf("AESSIVKeyManager must support %s", testutil.AESSIVTypeURL)
179	}
180	if km.DoesSupport("some bad type") {
181		t.Errorf("AESSIVKeyManager must only support %s", testutil.AESSIVTypeURL)
182	}
183}
184
185func TestAESSIVTypeURL(t *testing.T) {
186	km, err := registry.GetKeyManager(testutil.AESSIVTypeURL)
187	if err != nil {
188		t.Errorf("cannot obtain AESSIV key manager: %s", err)
189	}
190	if kt := km.TypeURL(); kt != testutil.AESSIVTypeURL {
191		t.Errorf("km.TypeURL() = %s; want %s", kt, testutil.AESSIVTypeURL)
192	}
193}
194
195func TestAESSIVKeyMaterialType(t *testing.T) {
196	km, err := registry.GetKeyManager(testutil.AESSIVTypeURL)
197	if err != nil {
198		t.Fatalf("registry.GetKeyManager(%q) err = %v, want nil", testutil.AESSIVTypeURL, err)
199	}
200	keyManager, ok := km.(internalregistry.DerivableKeyManager)
201	if !ok {
202		t.Fatalf("key manager is not DerivableKeyManager")
203	}
204	if got, want := keyManager.KeyMaterialType(), tpb.KeyData_SYMMETRIC; got != want {
205		t.Errorf("KeyMaterialType() = %v, want %v", got, want)
206	}
207}
208
209func TestAESSIVDeriveKey(t *testing.T) {
210	km, err := registry.GetKeyManager(testutil.AESSIVTypeURL)
211	if err != nil {
212		t.Fatalf("registry.GetKeyManager(%q) err = %v, want nil", testutil.AESSIVTypeURL, err)
213	}
214	keyManager, ok := km.(internalregistry.DerivableKeyManager)
215	if !ok {
216		t.Fatalf("key manager is not DerivableKeyManager")
217	}
218	keyFormat, err := proto.Marshal(&aspb.AesSivKeyFormat{
219		KeySize: subtle.AESSIVKeySize,
220		Version: testutil.AESSIVKeyVersion,
221	})
222	if err != nil {
223		t.Errorf("proto.Marshal() = %v; want nil", err)
224	}
225	rand := random.GetRandomBytes(subtle.AESSIVKeySize)
226	buf := &bytes.Buffer{}
227	buf.Write(rand) // never returns a non-nil error
228	k, err := keyManager.DeriveKey(keyFormat, buf)
229	if err != nil {
230		t.Fatalf("keyManager.DeriveKey() err = %v, want nil", err)
231	}
232	key := k.(*aspb.AesSivKey)
233	if got, want := len(key.GetKeyValue()), subtle.AESSIVKeySize; got != want {
234		t.Errorf("key length = %d, want %d", got, want)
235	}
236	if diff := cmp.Diff(key.GetKeyValue(), rand); diff != "" {
237		t.Errorf("incorrect derived key: diff = %v", diff)
238	}
239}
240
241func TestAESSIVDeriveKeyFailsWithInvalidKeyFormats(t *testing.T) {
242	km, err := registry.GetKeyManager(testutil.AESSIVTypeURL)
243	if err != nil {
244		t.Fatalf("registry.GetKeyManager(%q) err = %v, want nil", testutil.AESSIVTypeURL, err)
245	}
246	keyManager, ok := km.(internalregistry.DerivableKeyManager)
247	if !ok {
248		t.Fatalf("key manager is not DerivableKeyManager")
249	}
250	for _, test := range []struct {
251		name    string
252		keySize uint32
253		version uint32
254	}{
255		{
256			name:    "invalid key size",
257			keySize: subtle.AESSIVKeySize - 1,
258			version: testutil.AESSIVKeyVersion,
259		},
260		{
261			name:    "invalid version",
262			keySize: subtle.AESSIVKeySize,
263			version: testutil.AESSIVKeyVersion + 1,
264		},
265		{
266			name:    "zero key size and version",
267			keySize: 0,
268			version: 0,
269		},
270	} {
271		t.Run(test.name, func(t *testing.T) {
272			keyFormat := &aspb.AesSivKeyFormat{
273				KeySize: test.keySize,
274				Version: test.version,
275			}
276			serializedKeyFormat, err := proto.Marshal(keyFormat)
277			if err != nil {
278				t.Errorf("proto.Marshal() = %v; want nil", err)
279			}
280			buf := bytes.NewBuffer(random.GetRandomBytes(subtle.AESSIVKeySize))
281			if _, err := keyManager.DeriveKey(serializedKeyFormat, buf); err == nil {
282				t.Errorf("keyManager.DeriveKey() err = nil, want non-nil")
283			}
284		})
285	}
286}
287
288func TestAESSIVDeriveKeyFailsWithMalformedKeyFormats(t *testing.T) {
289	km, err := registry.GetKeyManager(testutil.AESSIVTypeURL)
290	if err != nil {
291		t.Fatalf("registry.GetKeyManager(%q) err = %v, want nil", testutil.AESSIVTypeURL, err)
292	}
293	keyManager, ok := km.(internalregistry.DerivableKeyManager)
294	if !ok {
295		t.Fatalf("key manager is not DerivableKeyManager")
296	}
297	// Proto messages start with a VarInt, which always ends with a byte with the
298	// MSB unset, so 0x80 is invalid.
299	invalidSerialization, err := hex.DecodeString("80")
300	if err != nil {
301		t.Errorf("hex.DecodeString() err = %v, want nil", err)
302	}
303	for _, test := range []struct {
304		name      string
305		keyFormat []byte
306	}{
307		{
308			name:      "nil",
309			keyFormat: nil,
310		},
311		{
312			name:      "invalid serialization",
313			keyFormat: invalidSerialization,
314		},
315	} {
316		t.Run(test.name, func(t *testing.T) {
317			buf := bytes.NewBuffer(random.GetRandomBytes(subtle.AESSIVKeySize))
318			if _, err := keyManager.DeriveKey(test.keyFormat, buf); err == nil {
319				t.Errorf("keyManager.DeriveKey() err = nil, want non-nil")
320			}
321		})
322	}
323}
324
325func TestAESSIVDeriveKeyFailsWithInsufficientRandomness(t *testing.T) {
326	km, err := registry.GetKeyManager(testutil.AESSIVTypeURL)
327	if err != nil {
328		t.Fatalf("registry.GetKeyManager(%q) err = %v, want nil", testutil.AESSIVTypeURL, err)
329	}
330	keyManager, ok := km.(internalregistry.DerivableKeyManager)
331	if !ok {
332		t.Fatalf("key manager is not DerivableKeyManager")
333	}
334	keyFormat, err := proto.Marshal(&aspb.AesSivKeyFormat{
335		KeySize: subtle.AESSIVKeySize,
336		Version: testutil.AESSIVKeyVersion,
337	})
338	if err != nil {
339		t.Fatalf("proto.Marshal() err = %v, want nil", err)
340	}
341	{
342		buf := bytes.NewBuffer(random.GetRandomBytes(subtle.AESSIVKeySize))
343		if _, err := keyManager.DeriveKey(keyFormat, buf); err != nil {
344			t.Errorf("keyManager.DeriveKey() err = %v, want nil", err)
345		}
346	}
347	{
348		insufficientBuf := bytes.NewBuffer(random.GetRandomBytes(subtle.AESSIVKeySize - 1))
349		if _, err := keyManager.DeriveKey(keyFormat, insufficientBuf); err == nil {
350			t.Errorf("keyManager.DeriveKey() err = nil, want non-nil")
351		}
352	}
353}
354
355func validateAESSIVPrimitive(p interface{}, key *aspb.AesSivKey) error {
356	cipher := p.(*subtle.AESSIV)
357	// try to encrypt and decrypt
358	pt := random.GetRandomBytes(32)
359	aad := random.GetRandomBytes(32)
360	ct, err := cipher.EncryptDeterministically(pt, aad)
361	if err != nil {
362		return fmt.Errorf("encryption failed")
363	}
364	decrypted, err := cipher.DecryptDeterministically(ct, aad)
365	if err != nil {
366		return fmt.Errorf("decryption failed")
367	}
368	if !bytes.Equal(decrypted, pt) {
369		return fmt.Errorf("decryption failed")
370	}
371	return nil
372}
373
374func validateAESSIVKey(key *aspb.AesSivKey) error {
375	if key.Version != testutil.AESSIVKeyVersion {
376		return fmt.Errorf("incorrect key version: keyVersion != %d", testutil.AESSIVKeyVersion)
377	}
378	if uint32(len(key.KeyValue)) != subtle.AESSIVKeySize {
379		return fmt.Errorf("incorrect key size: keySize != %d", subtle.AESSIVKeySize)
380	}
381
382	// Try to encrypt and decrypt.
383	p, err := subtle.NewAESSIV(key.KeyValue)
384	if err != nil {
385		return fmt.Errorf("invalid key: %v", key.KeyValue)
386	}
387	return validateAESSIVPrimitive(p, key)
388}
389