xref: /aosp_15_r20/external/tink/go/aead/aead_factory_test.go (revision e7b1675dde1b92d52ec075b0a92829627f2c52a5)
1// Copyright 2018 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 aead_test
18
19import (
20	"bytes"
21	"errors"
22	"fmt"
23	"strings"
24	"testing"
25
26	"github.com/google/go-cmp/cmp"
27	"github.com/google/go-cmp/cmp/cmpopts"
28	"github.com/google/tink/go/aead"
29	"github.com/google/tink/go/core/cryptofmt"
30	"github.com/google/tink/go/core/registry"
31	"github.com/google/tink/go/insecurecleartextkeyset"
32	"github.com/google/tink/go/internal/internalregistry"
33	"github.com/google/tink/go/internal/testing/stubkeymanager"
34	"github.com/google/tink/go/keyset"
35	"github.com/google/tink/go/monitoring"
36	"github.com/google/tink/go/signature"
37	"github.com/google/tink/go/subtle/random"
38	"github.com/google/tink/go/testing/fakemonitoring"
39	"github.com/google/tink/go/testkeyset"
40	"github.com/google/tink/go/testutil"
41	"github.com/google/tink/go/tink"
42
43	"github.com/google/tink/go/aead/subtle"
44	agpb "github.com/google/tink/go/proto/aes_gcm_go_proto"
45	tinkpb "github.com/google/tink/go/proto/tink_go_proto"
46)
47
48func TestFactoryMultipleKeys(t *testing.T) {
49	// encrypt with non-raw key
50	keyset := testutil.NewTestAESGCMKeyset(tinkpb.OutputPrefixType_TINK)
51	primaryKey := keyset.Key[0]
52	if primaryKey.OutputPrefixType == tinkpb.OutputPrefixType_RAW {
53		t.Errorf("expect a non-raw key")
54	}
55	keysetHandle, _ := testkeyset.NewHandle(keyset)
56	a, err := aead.New(keysetHandle)
57	if err != nil {
58		t.Errorf("aead.New failed: %s", err)
59	}
60	expectedPrefix, _ := cryptofmt.OutputPrefix(primaryKey)
61	if err := validateAEADFactoryCipher(a, a, expectedPrefix); err != nil {
62		t.Errorf("invalid cipher: %s", err)
63	}
64
65	// encrypt with a non-primary RAW key and decrypt with the keyset
66	rawKey := keyset.Key[1]
67	if rawKey.OutputPrefixType != tinkpb.OutputPrefixType_RAW {
68		t.Errorf("expect a raw key")
69	}
70	keyset2 := testutil.NewKeyset(rawKey.KeyId, []*tinkpb.Keyset_Key{rawKey})
71	keysetHandle2, _ := testkeyset.NewHandle(keyset2)
72	a2, err := aead.New(keysetHandle2)
73	if err != nil {
74		t.Errorf("aead.New failed: %s", err)
75	}
76	if err := validateAEADFactoryCipher(a2, a, cryptofmt.RawPrefix); err != nil {
77		t.Errorf("invalid cipher: %s", err)
78	}
79
80	// encrypt with a random key not in the keyset, decrypt with the keyset should fail
81	keyset2 = testutil.NewTestAESGCMKeyset(tinkpb.OutputPrefixType_TINK)
82	primaryKey = keyset2.Key[0]
83	expectedPrefix, _ = cryptofmt.OutputPrefix(primaryKey)
84	keysetHandle2, _ = testkeyset.NewHandle(keyset2)
85	a2, err = aead.New(keysetHandle2)
86	if err != nil {
87		t.Errorf("aead.New failed: %s", err)
88	}
89	err = validateAEADFactoryCipher(a2, a, expectedPrefix)
90	if err == nil || !strings.Contains(err.Error(), "decryption failed") {
91		t.Errorf("expect decryption to fail with random key: %s", err)
92	}
93}
94
95func TestFactoryRawKeyAsPrimary(t *testing.T) {
96	keyset := testutil.NewTestAESGCMKeyset(tinkpb.OutputPrefixType_RAW)
97	if keyset.Key[0].OutputPrefixType != tinkpb.OutputPrefixType_RAW {
98		t.Errorf("primary key is not a raw key")
99	}
100	keysetHandle, _ := testkeyset.NewHandle(keyset)
101
102	a, err := aead.New(keysetHandle)
103	if err != nil {
104		t.Errorf("cannot get primitive from keyset handle: %s", err)
105	}
106	if err := validateAEADFactoryCipher(a, a, cryptofmt.RawPrefix); err != nil {
107		t.Errorf("invalid cipher: %s", err)
108	}
109}
110
111func validateAEADFactoryCipher(encryptCipher, decryptCipher tink.AEAD, expectedPrefix string) error {
112	prefixSize := len(expectedPrefix)
113	// regular plaintext
114	pt := random.GetRandomBytes(20)
115	ad := random.GetRandomBytes(20)
116	ct, err := encryptCipher.Encrypt(pt, ad)
117	if err != nil {
118		return fmt.Errorf("encryption failed with regular plaintext: %s", err)
119	}
120	decrypted, err := decryptCipher.Decrypt(ct, ad)
121	if err != nil || !bytes.Equal(decrypted, pt) {
122		return fmt.Errorf("decryption failed with regular plaintext: err: %s, pt: %s, decrypted: %s",
123			err, pt, decrypted)
124	}
125	if string(ct[:prefixSize]) != expectedPrefix {
126		return fmt.Errorf("incorrect prefix with regular plaintext")
127	}
128	if prefixSize+len(pt)+subtle.AESGCMIVSize+subtle.AESGCMTagSize != len(ct) {
129		return fmt.Errorf("lengths of plaintext and ciphertext don't match with regular plaintext")
130	}
131
132	// short plaintext
133	pt = random.GetRandomBytes(1)
134	ct, err = encryptCipher.Encrypt(pt, ad)
135	if err != nil {
136		return fmt.Errorf("encryption failed with short plaintext: %s", err)
137	}
138	decrypted, err = decryptCipher.Decrypt(ct, ad)
139	if err != nil || !bytes.Equal(decrypted, pt) {
140		return fmt.Errorf("decryption failed with short plaintext: err: %s, pt: %s, decrypted: %s",
141			err, pt, decrypted)
142	}
143	if string(ct[:prefixSize]) != expectedPrefix {
144		return fmt.Errorf("incorrect prefix with short plaintext")
145	}
146	if prefixSize+len(pt)+subtle.AESGCMIVSize+subtle.AESGCMTagSize != len(ct) {
147		return fmt.Errorf("lengths of plaintext and ciphertext don't match with short plaintext")
148	}
149	return nil
150}
151
152func TestFactoryWithInvalidPrimitiveSetType(t *testing.T) {
153	wrongKH, err := keyset.NewHandle(signature.ECDSAP256KeyTemplate())
154	if err != nil {
155		t.Fatalf("failed to build *keyset.Handle: %s", err)
156	}
157
158	_, err = aead.New(wrongKH)
159	if err == nil {
160		t.Fatalf("calling New() with wrong *keyset.Handle should fail")
161	}
162}
163
164func TestFactoryWithValidPrimitiveSetType(t *testing.T) {
165	goodKH, err := keyset.NewHandle(aead.AES128GCMKeyTemplate())
166	if err != nil {
167		t.Fatalf("failed to build *keyset.Handle: %s", err)
168	}
169
170	_, err = aead.New(goodKH)
171	if err != nil {
172		t.Fatalf("calling New() with good *keyset.Handle failed: %s", err)
173	}
174}
175
176func TestPrimitiveFactoryWithMonitoringAnnotationsLogsEncryptionDecryptionWithPrefix(t *testing.T) {
177	defer internalregistry.ClearMonitoringClient()
178	client := fakemonitoring.NewClient("fake-client")
179	if err := internalregistry.RegisterMonitoringClient(client); err != nil {
180		t.Fatalf("internalregistry.RegisterMonitoringClient() err = %v, want nil", err)
181	}
182	kh, err := keyset.NewHandle(aead.AES128GCMKeyTemplate())
183	if err != nil {
184		t.Fatalf("keyset.NewHandle() err = %v, want nil", err)
185	}
186	// Annotations are only supported throught the `insecurecleartextkeyset` API.
187	buff := &bytes.Buffer{}
188	if err := insecurecleartextkeyset.Write(kh, keyset.NewBinaryWriter(buff)); err != nil {
189		t.Fatalf("insecurecleartextkeyset.Write() err = %v, want nil", err)
190	}
191	annotations := map[string]string{"foo": "bar"}
192	mh, err := insecurecleartextkeyset.Read(keyset.NewBinaryReader(buff), keyset.WithAnnotations(annotations))
193	if err != nil {
194		t.Fatalf("insecurecleartextkeyset.Read() err = %v, want nil", err)
195	}
196	p, err := aead.New(mh)
197	if err != nil {
198		t.Fatalf("aead.New() err = %v, want nil", err)
199	}
200	data := []byte("HELLO_WORLD")
201	ad := []byte("_!")
202	ct, err := p.Encrypt(data, ad)
203	if err != nil {
204		t.Fatalf("p.Encrypt() err = %v, want nil", err)
205	}
206	if _, err := p.Decrypt(ct, ad); err != nil {
207		t.Fatalf("p.Decrypt() err = %v, want nil", err)
208	}
209	failures := client.Failures()
210	if len(failures) != 0 {
211		t.Errorf("len(client.Failures()) = %d, want = 0", len(failures))
212	}
213	got := client.Events()
214	wantKeysetInfo := monitoring.NewKeysetInfo(
215		annotations,
216		kh.KeysetInfo().GetPrimaryKeyId(),
217		[]*monitoring.Entry{
218			{
219				KeyID:     kh.KeysetInfo().GetPrimaryKeyId(),
220				Status:    monitoring.Enabled,
221				KeyType:   "tink.AesGcmKey",
222				KeyPrefix: "TINK",
223			},
224		},
225	)
226	want := []*fakemonitoring.LogEvent{
227		{
228			KeyID:    mh.KeysetInfo().GetPrimaryKeyId(),
229			NumBytes: len(data),
230			Context:  monitoring.NewContext("aead", "encrypt", wantKeysetInfo),
231		},
232		{
233			KeyID: mh.KeysetInfo().GetPrimaryKeyId(),
234			// ciphertext was encrypted with a key that has TINK ouput prefix. This adds a 5 bytes prefix
235			// to the ciphertext. This prefix is not included in `Log` call.
236			NumBytes: len(ct) - cryptofmt.NonRawPrefixSize,
237			Context:  monitoring.NewContext("aead", "decrypt", wantKeysetInfo),
238		},
239	}
240	if cmp.Diff(got, want) != "" {
241		t.Errorf("%v", cmp.Diff(got, want))
242	}
243}
244
245func TestPrimitiveFactoryWithMonitoringAnnotationsLogsEncryptionDecryptionWithoutPrefix(t *testing.T) {
246	defer internalregistry.ClearMonitoringClient()
247	client := fakemonitoring.NewClient("fake-client")
248	if err := internalregistry.RegisterMonitoringClient(client); err != nil {
249		t.Fatalf("internalregistry.RegisterMonitoringClient() err = %v, want nil", err)
250	}
251	kh, err := keyset.NewHandle(aead.AES256GCMNoPrefixKeyTemplate())
252	if err != nil {
253		t.Fatalf("keyset.NewHandle() err = %v, want nil", err)
254	}
255	// Annotations are only supported throught the `insecurecleartextkeyset` API.
256	buff := &bytes.Buffer{}
257	if err := insecurecleartextkeyset.Write(kh, keyset.NewBinaryWriter(buff)); err != nil {
258		t.Fatalf("insecurecleartextkeyset.Write() err = %v, want nil", err)
259	}
260	annotations := map[string]string{"foo": "bar"}
261	mh, err := insecurecleartextkeyset.Read(keyset.NewBinaryReader(buff), keyset.WithAnnotations(annotations))
262	if err != nil {
263		t.Fatalf("insecurecleartextkeyset.Read() err = %v, want nil", err)
264	}
265	p, err := aead.New(mh)
266	if err != nil {
267		t.Fatalf("aead.New() err = %v, want nil", err)
268	}
269	data := []byte("HELLO_WORLD")
270	ct, err := p.Encrypt(data, nil)
271	if err != nil {
272		t.Fatalf("p.Encrypt() err = %v, want nil", err)
273	}
274	if _, err := p.Decrypt(ct, nil); err != nil {
275		t.Fatalf("p.Decrypt() err = %v, want nil", err)
276	}
277	failures := client.Failures()
278	if len(failures) != 0 {
279		t.Errorf("len(client.Failures()) = %d, want = 0", len(failures))
280	}
281	got := client.Events()
282	wantKeysetInfo := monitoring.NewKeysetInfo(
283		annotations,
284		kh.KeysetInfo().GetPrimaryKeyId(),
285		[]*monitoring.Entry{
286			{
287				KeyID:     kh.KeysetInfo().GetPrimaryKeyId(),
288				Status:    monitoring.Enabled,
289				KeyType:   "tink.AesGcmKey",
290				KeyPrefix: "RAW",
291			},
292		},
293	)
294	want := []*fakemonitoring.LogEvent{
295		{
296			KeyID:    mh.KeysetInfo().GetPrimaryKeyId(),
297			NumBytes: len(data),
298			Context:  monitoring.NewContext("aead", "encrypt", wantKeysetInfo),
299		},
300		{
301			KeyID:    mh.KeysetInfo().GetPrimaryKeyId(),
302			NumBytes: len(ct),
303			Context:  monitoring.NewContext("aead", "decrypt", wantKeysetInfo),
304		},
305	}
306	if cmp.Diff(got, want) != "" {
307		t.Errorf("%v", cmp.Diff(got, want))
308	}
309}
310
311func TestPrimitiveFactoryMonitoringWithAnnotatiosMultipleKeysLogsEncryptionDecryption(t *testing.T) {
312	defer internalregistry.ClearMonitoringClient()
313	client := fakemonitoring.NewClient("fake-client")
314	if err := internalregistry.RegisterMonitoringClient(client); err != nil {
315		t.Fatalf("registry.RegisterMonitoringClient() err = %v, want nil", err)
316	}
317	manager := keyset.NewManager()
318	keyTemplates := []*tinkpb.KeyTemplate{
319		aead.AES128GCMKeyTemplate(),
320		aead.AES256GCMNoPrefixKeyTemplate(),
321		aead.AES128CTRHMACSHA256KeyTemplate(),
322		aead.XChaCha20Poly1305KeyTemplate(),
323	}
324	keyIDs := make([]uint32, len(keyTemplates), len(keyTemplates))
325	var err error
326	for i, kt := range keyTemplates {
327		keyIDs[i], err = manager.Add(kt)
328		if err != nil {
329			t.Fatalf("manager.Add(%v) err = %v, want nil", kt, err)
330		}
331	}
332	if err := manager.SetPrimary(keyIDs[1]); err != nil {
333		t.Fatalf("manager.SetPrimary(%d) err = %v, want nil", keyIDs[1], err)
334	}
335	if err := manager.Disable(keyIDs[0]); err != nil {
336		t.Fatalf("manager.Disable(%d) err = %v, want nil", keyIDs[0], err)
337	}
338	kh, err := manager.Handle()
339	if err != nil {
340		t.Fatalf("manager.Handle() err = %v, want nil", err)
341	}
342	// Annotations are only supported throught the `insecurecleartextkeyset` API.
343	buff := &bytes.Buffer{}
344	if err := insecurecleartextkeyset.Write(kh, keyset.NewBinaryWriter(buff)); err != nil {
345		t.Fatalf("insecurecleartextkeyset.Write() err = %v, want nil", err)
346	}
347	annotations := map[string]string{"foo": "bar"}
348	mh, err := insecurecleartextkeyset.Read(keyset.NewBinaryReader(buff), keyset.WithAnnotations(annotations))
349	if err != nil {
350		t.Fatalf("insecurecleartextkeyset.Read() err = %v, want nil", err)
351	}
352	p, err := aead.New(mh)
353	if err != nil {
354		t.Fatalf("aead.New() err = %v, want nil", err)
355	}
356	failures := len(client.Failures())
357	if failures != 0 {
358		t.Errorf("len(client.Failures()) = %d, want 0", failures)
359	}
360	data := []byte("YELLOW_ORANGE")
361	ct, err := p.Encrypt(data, nil)
362	if err != nil {
363		t.Fatalf("p.Encrypt() err = %v, want nil", err)
364	}
365	if _, err := p.Decrypt(ct, nil); err != nil {
366		t.Fatalf("p.Decrypt() err = %v, want nil", err)
367	}
368	got := client.Events()
369	wantKeysetInfo := monitoring.NewKeysetInfo(annotations, keyIDs[1], []*monitoring.Entry{
370		{
371			KeyID:     keyIDs[1],
372			Status:    monitoring.Enabled,
373			KeyType:   "tink.AesGcmKey",
374			KeyPrefix: "RAW",
375		},
376		{
377			KeyID:     keyIDs[2],
378			Status:    monitoring.Enabled,
379			KeyType:   "tink.AesCtrHmacAeadKey",
380			KeyPrefix: "TINK",
381		},
382		{
383			KeyID:     keyIDs[3],
384			Status:    monitoring.Enabled,
385			KeyType:   "tink.XChaCha20Poly1305Key",
386			KeyPrefix: "TINK",
387		},
388	})
389	want := []*fakemonitoring.LogEvent{
390		{
391			KeyID:    keyIDs[1],
392			NumBytes: len(data),
393			Context: monitoring.NewContext(
394				"aead",
395				"encrypt",
396				wantKeysetInfo,
397			),
398		},
399		{
400			KeyID:    keyIDs[1],
401			NumBytes: len(ct),
402			Context: monitoring.NewContext(
403				"aead",
404				"decrypt",
405				wantKeysetInfo,
406			),
407		},
408	}
409	// sort by keyID to avoid non deterministic order.
410	entryLessFunc := func(a, b *monitoring.Entry) bool {
411		return a.KeyID < b.KeyID
412	}
413	if !cmp.Equal(got, want, cmpopts.SortSlices(entryLessFunc)) {
414		t.Errorf("got = %v, want = %v, with diff: %v", got, want, cmp.Diff(got, want))
415	}
416}
417
418func TestPrimitiveFactoryWithMonitoringAnnotationsEncryptionFailureIsLogged(t *testing.T) {
419	defer internalregistry.ClearMonitoringClient()
420	client := &fakemonitoring.Client{Name: ""}
421	if err := internalregistry.RegisterMonitoringClient(client); err != nil {
422		t.Fatalf("internalregistry.RegisterMonitoringClient() err = %v, want nil", err)
423	}
424	typeURL := "TestFactoryWithMonitoringPrimitiveEncryptionFailureIsLogged"
425	template := &tinkpb.KeyTemplate{
426		TypeUrl:          typeURL,
427		OutputPrefixType: tinkpb.OutputPrefixType_LEGACY,
428	}
429	km := &stubkeymanager.StubKeyManager{
430		URL:  typeURL,
431		Key:  &agpb.AesGcmKey{},
432		Prim: &testutil.AlwaysFailingAead{Error: errors.New("failed")},
433		KeyData: &tinkpb.KeyData{
434			TypeUrl:         typeURL,
435			KeyMaterialType: tinkpb.KeyData_SYMMETRIC,
436			Value:           []byte("serialized_key"),
437		},
438	}
439	if err := registry.RegisterKeyManager(km); err != nil {
440		t.Fatalf("registry.RegisterKeyManager() err = %v, want nil", err)
441	}
442	kh, err := keyset.NewHandle(template)
443	if err != nil {
444		t.Fatalf("keyset.NewHandle() err = %v, want nil", err)
445	}
446	// Annotations are only supported throught the `insecurecleartextkeyset` API.
447	buff := &bytes.Buffer{}
448	if err := insecurecleartextkeyset.Write(kh, keyset.NewBinaryWriter(buff)); err != nil {
449		t.Fatalf("insecurecleartextkeyset.Write() err = %v, want nil", err)
450	}
451	annotations := map[string]string{"foo": "bar"}
452	mh, err := insecurecleartextkeyset.Read(keyset.NewBinaryReader(buff), keyset.WithAnnotations(annotations))
453	if err != nil {
454		t.Fatalf("insecurecleartextkeyset.Read() err = %v, want nil", err)
455	}
456	p, err := aead.New(mh)
457	if err != nil {
458		t.Fatalf("aead.New() err = %v, want nil", err)
459	}
460	if _, err := p.Encrypt(nil, nil); err == nil {
461		t.Fatalf("Encrypt() err = nil, want error")
462	}
463	got := client.Failures()
464	want := []*fakemonitoring.LogFailure{
465		{
466			Context: monitoring.NewContext(
467				"aead",
468				"encrypt",
469				monitoring.NewKeysetInfo(
470					annotations,
471					kh.KeysetInfo().GetPrimaryKeyId(),
472					[]*monitoring.Entry{
473						{
474							KeyID:     kh.KeysetInfo().GetPrimaryKeyId(),
475							Status:    monitoring.Enabled,
476							KeyType:   typeURL,
477							KeyPrefix: "LEGACY",
478						},
479					},
480				),
481			),
482		},
483	}
484	if cmp.Diff(got, want) != "" {
485		t.Errorf("%v", cmp.Diff(got, want))
486	}
487}
488
489func TestPrimitiveFactoryWithMonitoringAnnotationsDecryptionFailureIsLogged(t *testing.T) {
490	defer internalregistry.ClearMonitoringClient()
491	client := fakemonitoring.NewClient("fake-client")
492	if err := internalregistry.RegisterMonitoringClient(client); err != nil {
493		t.Fatalf("internalregistry.RegisterMonitoringClient() err = %v, want nil", err)
494	}
495	kh, err := keyset.NewHandle(aead.AES128GCMKeyTemplate())
496	if err != nil {
497		t.Fatalf("keyset.NewHandle() err = %v, want nil", err)
498	}
499	// Annotations are only supported throught the `insecurecleartextkeyset` API.
500	buff := &bytes.Buffer{}
501	if err := insecurecleartextkeyset.Write(kh, keyset.NewBinaryWriter(buff)); err != nil {
502		t.Fatalf("insecurecleartextkeyset.Write() err = %v, want nil", err)
503	}
504	annotations := map[string]string{"foo": "bar"}
505	mh, err := insecurecleartextkeyset.Read(keyset.NewBinaryReader(buff), keyset.WithAnnotations(annotations))
506	if err != nil {
507		t.Fatalf("insecurecleartextkeyset.Read() err = %v, want nil", err)
508	}
509	p, err := aead.New(mh)
510	if err != nil {
511		t.Fatalf("aead.New() err = %v, want nil", err)
512	}
513	if _, err := p.Decrypt([]byte("invalid_data"), nil); err == nil {
514		t.Fatalf("Decrypt() err = nil, want error")
515	}
516	got := client.Failures()
517	want := []*fakemonitoring.LogFailure{
518		{
519			Context: monitoring.NewContext(
520				"aead",
521				"decrypt",
522				monitoring.NewKeysetInfo(
523					annotations,
524					kh.KeysetInfo().GetPrimaryKeyId(),
525					[]*monitoring.Entry{
526						{
527							KeyID:     kh.KeysetInfo().GetPrimaryKeyId(),
528							Status:    monitoring.Enabled,
529							KeyType:   "tink.AesGcmKey",
530							KeyPrefix: "TINK",
531						},
532					},
533				),
534			),
535		},
536	}
537	if cmp.Diff(got, want) != "" {
538		t.Errorf("%v", cmp.Diff(got, want))
539	}
540}
541
542func TestFactoryWithMonitoringMultiplePrimitivesLogOperations(t *testing.T) {
543	defer internalregistry.ClearMonitoringClient()
544	client := &fakemonitoring.Client{Name: ""}
545	if err := internalregistry.RegisterMonitoringClient(client); err != nil {
546		t.Fatalf("internalregistry.RegisterMonitoringClient() err = %v, want nil", err)
547	}
548	kh1, err := keyset.NewHandle(aead.AES128GCMKeyTemplate())
549	if err != nil {
550		t.Fatalf("keyset.NewHandle() err = %v, want nil", err)
551	}
552	// Annotations are only supported throught the `insecurecleartextkeyset` API.
553	buff := &bytes.Buffer{}
554	if err := insecurecleartextkeyset.Write(kh1, keyset.NewBinaryWriter(buff)); err != nil {
555		t.Fatalf("insecurecleartextkeyset.Write() err = %v, want nil", err)
556	}
557	annotations := map[string]string{"foo": "bar"}
558	mh1, err := insecurecleartextkeyset.Read(keyset.NewBinaryReader(buff), keyset.WithAnnotations(annotations))
559	if err != nil {
560		t.Fatalf("insecurecleartextkeyset.Read() err = %v, want nil", err)
561	}
562	p1, err := aead.New(mh1)
563	if err != nil {
564		t.Fatalf("aead.New() err = %v, want nil", err)
565	}
566	kh2, err := keyset.NewHandle(aead.AES128CTRHMACSHA256KeyTemplate())
567	if err != nil {
568		t.Fatalf("keyset.NewHandle() err = %v, want nil", err)
569	}
570	buff.Reset()
571	if err := insecurecleartextkeyset.Write(kh2, keyset.NewBinaryWriter(buff)); err != nil {
572		t.Fatalf("insecurecleartextkeyset.Write() err = %v, want nil", err)
573	}
574	mh2, err := insecurecleartextkeyset.Read(keyset.NewBinaryReader(buff), keyset.WithAnnotations(annotations))
575	if err != nil {
576		t.Fatalf("insecurecleartextkeyset.Read() err = %v, want nil", err)
577	}
578	p2, err := aead.New(mh2)
579	if err != nil {
580		t.Fatalf("aead.New() err = %v, want nil", err)
581	}
582	d1 := []byte("YELLOW_ORANGE")
583	if _, err := p1.Encrypt(d1, nil); err != nil {
584		t.Fatalf("p1.Encrypt() err = %v, want nil", err)
585	}
586	d2 := []byte("ORANGE_BLUE")
587	if _, err := p2.Encrypt(d2, nil); err != nil {
588		t.Fatalf("p2.Encrypt() err = %v, want nil", err)
589	}
590	got := client.Events()
591	want := []*fakemonitoring.LogEvent{
592		{
593			KeyID:    kh1.KeysetInfo().GetPrimaryKeyId(),
594			NumBytes: len(d1),
595			Context: monitoring.NewContext(
596				"aead",
597				"encrypt",
598				monitoring.NewKeysetInfo(
599					annotations,
600					kh1.KeysetInfo().GetPrimaryKeyId(),
601					[]*monitoring.Entry{
602						{
603							KeyID:     kh1.KeysetInfo().GetPrimaryKeyId(),
604							Status:    monitoring.Enabled,
605							KeyType:   "tink.AesGcmKey",
606							KeyPrefix: "TINK",
607						},
608					},
609				),
610			),
611		},
612		{
613			KeyID:    kh2.KeysetInfo().GetPrimaryKeyId(),
614			NumBytes: len(d2),
615			Context: monitoring.NewContext(
616				"aead",
617				"encrypt",
618				monitoring.NewKeysetInfo(
619					annotations,
620					kh2.KeysetInfo().GetPrimaryKeyId(),
621					[]*monitoring.Entry{
622						{
623							KeyID:     kh2.KeysetInfo().GetPrimaryKeyId(),
624							Status:    monitoring.Enabled,
625							KeyType:   "tink.AesCtrHmacAeadKey",
626							KeyPrefix: "TINK",
627						},
628					},
629				),
630			),
631		},
632	}
633	if !cmp.Equal(got, want) {
634		t.Errorf("got = %v, want = %v, with diff: %v", got, want, cmp.Diff(got, want))
635	}
636}
637
638func TestPrimitiveFactoryEncryptDecryptWithoutAnnotationsDoesNothing(t *testing.T) {
639	defer internalregistry.ClearMonitoringClient()
640	client := fakemonitoring.NewClient("fake-client")
641	if err := internalregistry.RegisterMonitoringClient(client); err != nil {
642		t.Fatalf("internalregistry.RegisterMonitoringClient() err = %v, want nil", err)
643	}
644	kh, err := keyset.NewHandle(aead.AES128GCMKeyTemplate())
645	if err != nil {
646		t.Fatalf("keyset.NewHandle() err = %v, want nil", err)
647	}
648	p, err := aead.New(kh)
649	if err != nil {
650		t.Fatalf("aead.New() err = %v, want nil", err)
651	}
652	data := []byte("YELLOW_ORANGE")
653	ct, err := p.Encrypt(data, nil)
654	if err != nil {
655		t.Fatalf("p.Encrypt() err = %v, want nil", err)
656	}
657	if _, err := p.Decrypt(ct, nil); err != nil {
658		t.Fatalf("p.Decrypt() err = %v, want nil", err)
659	}
660	got := client.Events()
661	if len(got) != 0 {
662		t.Errorf("len(client.Events()) = %d, want 0", len(got))
663	}
664	failures := len(client.Failures())
665	if failures != 0 {
666		t.Errorf("len(client.Failures()) = %d, want 0", failures)
667	}
668}
669