xref: /aosp_15_r20/external/tink/go/hybrid/hybrid_factory_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 hybrid_test
18
19import (
20	"bytes"
21	"testing"
22
23	"github.com/google/go-cmp/cmp"
24	"github.com/google/go-cmp/cmp/cmpopts"
25	"google.golang.org/protobuf/proto"
26	"github.com/google/tink/go/aead"
27	"github.com/google/tink/go/core/cryptofmt"
28	"github.com/google/tink/go/hybrid"
29	"github.com/google/tink/go/insecurecleartextkeyset"
30	"github.com/google/tink/go/internal/internalregistry"
31	"github.com/google/tink/go/keyset"
32	"github.com/google/tink/go/monitoring"
33	"github.com/google/tink/go/signature"
34	"github.com/google/tink/go/subtle/random"
35	"github.com/google/tink/go/testing/fakemonitoring"
36	"github.com/google/tink/go/testkeyset"
37	"github.com/google/tink/go/testutil"
38	commonpb "github.com/google/tink/go/proto/common_go_proto"
39	tinkpb "github.com/google/tink/go/proto/tink_go_proto"
40)
41
42const eciesAEADHKDFPrivateKeyTypeURL = "type.googleapis.com/google.crypto.tink.EciesAeadHkdfPrivateKey"
43
44func TestHybridFactoryTest(t *testing.T) {
45	c := commonpb.EllipticCurveType_NIST_P256
46	ht := commonpb.HashType_SHA256
47	primaryPtFmt := commonpb.EcPointFormat_UNCOMPRESSED
48	rawPtFmt := commonpb.EcPointFormat_COMPRESSED
49	primaryDek := aead.AES128CTRHMACSHA256KeyTemplate()
50	rawDek := aead.AES128CTRHMACSHA256KeyTemplate()
51	primarySalt := []byte("some salt")
52	rawSalt := []byte("other salt")
53
54	primaryPrivProto, err := testutil.GenerateECIESAEADHKDFPrivateKey(c, ht, primaryPtFmt, primaryDek, primarySalt)
55	if err != nil {
56		t.Fatalf("testutil.GenerateECIESAEADHKDFPrivateKey(c, ht, primaryPtFmt, primaryDek, primarySalt) err = %v, want nil", err)
57	}
58	sPrimaryPriv, err := proto.Marshal(primaryPrivProto)
59	if err != nil {
60		t.Fatalf("proto.Marshal(primaryPrivProto) err = %v, want nil", err)
61	}
62
63	primaryPrivKey := testutil.NewKey(
64		testutil.NewKeyData(eciesAEADHKDFPrivateKeyTypeURL, sPrimaryPriv, tinkpb.KeyData_ASYMMETRIC_PRIVATE),
65		tinkpb.KeyStatusType_ENABLED, 8, tinkpb.OutputPrefixType_RAW)
66
67	rawPrivProto, err := testutil.GenerateECIESAEADHKDFPrivateKey(c, ht, rawPtFmt, rawDek, rawSalt)
68	if err != nil {
69		t.Fatalf("testutil.GenerateECIESAEADHKDFPrivateKey(c, ht, rawPtFmt, rawDek, rawSalt) err = %v, want nil", err)
70	}
71	sRawPriv, err := proto.Marshal(rawPrivProto)
72	if err != nil {
73		t.Fatalf("proto.Marshal(rawPrivProto) err = %v, want nil", err)
74	}
75	rawPrivKey := testutil.NewKey(
76		testutil.NewKeyData(eciesAEADHKDFPrivateKeyTypeURL, sRawPriv, tinkpb.KeyData_ASYMMETRIC_PRIVATE),
77		tinkpb.KeyStatusType_ENABLED, 11, tinkpb.OutputPrefixType_RAW)
78
79	privKeys := []*tinkpb.Keyset_Key{primaryPrivKey, rawPrivKey}
80	privKeyset := testutil.NewKeyset(privKeys[0].KeyId, privKeys)
81	khPriv, err := testkeyset.NewHandle(privKeyset)
82	if err != nil {
83		t.Fatalf("testkeyset.NewHandle(privKeyset) err = %v, want nil", err)
84	}
85
86	khPub, err := khPriv.Public()
87	if err != nil {
88		t.Fatalf("khPriv.Public() err = %v, want nil", err)
89	}
90
91	e, err := hybrid.NewHybridEncrypt(khPub)
92	if err != nil {
93		t.Fatalf("hybrid.NewHybridEncrypt(khPub) err = %v, want nil", err)
94	}
95	d, err := hybrid.NewHybridDecrypt(khPriv)
96	if err != nil {
97		t.Fatalf("hybrid.NewHybridDecrypt(khPriv) err = %v, want nil", err)
98	}
99
100	for i := 0; i < 1000; i++ {
101		pt := random.GetRandomBytes(20)
102		ci := random.GetRandomBytes(20)
103		ct, err := e.Encrypt(pt, ci)
104		if err != nil {
105			t.Fatalf("e.Encrypt(pt, ci) err = %v, want nil", err)
106		}
107		gotpt, err := d.Decrypt(ct, ci)
108		if err != nil {
109			t.Fatalf("d.Decrypt(ct, ci) err = %v, want nil", err)
110		}
111		if !bytes.Equal(pt, gotpt) {
112			t.Errorf("got plaintext %q, want %q", gotpt, pt)
113		}
114	}
115}
116
117func TestFactoryWithInvalidPrimitiveSetType(t *testing.T) {
118	wrongKH, err := keyset.NewHandle(signature.ECDSAP256KeyTemplate())
119	if err != nil {
120		t.Fatalf("keyset.NewHandle(signature.ECDSAP256KeyTemplate()) err = %v, want nil", err)
121	}
122
123	_, err = hybrid.NewHybridEncrypt(wrongKH)
124	if err == nil {
125		t.Error("hybrid.NewHybridEncrypt(wrongKH) err = nil, want not nil")
126	}
127
128	_, err = hybrid.NewHybridDecrypt(wrongKH)
129	if err == nil {
130		t.Error("hybrid.NewHybridDecrypt(wrongKH) err = nil, want not nil")
131	}
132}
133
134func TestFactoryWithValidPrimitiveSetType(t *testing.T) {
135	goodKH, err := keyset.NewHandle(hybrid.ECIESHKDFAES128GCMKeyTemplate())
136	if err != nil {
137		t.Fatalf("keyset.NewHandle(hybrid.ECIESHKDFAES128GCMKeyTemplate()) err = %v, want nil", err)
138	}
139
140	goodPublicKH, err := goodKH.Public()
141	if err != nil {
142		t.Fatalf("goodKH.Public() err = %v, want nil", err)
143	}
144	_, err = hybrid.NewHybridEncrypt(goodPublicKH)
145	if err != nil {
146		t.Errorf("hybrid.NewHybridEncrypt(goodPublicKH) err = %v, want nil", err)
147	}
148
149	_, err = hybrid.NewHybridDecrypt(goodKH)
150	if err != nil {
151		t.Errorf("hybrid.NewHybridDecrypt(goodKH) err = %v, want nil", err)
152	}
153}
154
155func TestPrimitiveFactoryFailsWhenKeysetHasNoPrimary(t *testing.T) {
156	curve := commonpb.EllipticCurveType_NIST_P256
157	hash := commonpb.HashType_SHA256
158	format := commonpb.EcPointFormat_UNCOMPRESSED
159	dek := aead.AES128CTRHMACSHA256KeyTemplate()
160	salt := []byte("some salt")
161	privProto, err := testutil.GenerateECIESAEADHKDFPrivateKey(curve, hash, format, dek, salt)
162	if err != nil {
163		t.Fatalf("testutil.GenerateECIESAEADHKDFPrivateKey(curve, hash, format, dek, salt) failed: %s", err)
164	}
165	serialized, err := proto.Marshal(privProto)
166	if err != nil {
167		t.Fatalf("proto.Marshal(privateProto) err = %v, want nil", err)
168	}
169	privKey := testutil.NewKey(
170		testutil.NewKeyData(eciesAEADHKDFPrivateKeyTypeURL, serialized, tinkpb.KeyData_ASYMMETRIC_PRIVATE),
171		tinkpb.KeyStatusType_ENABLED, 8, tinkpb.OutputPrefixType_RAW)
172	privKeysetWithoutPrimary := &tinkpb.Keyset{
173		Key: []*tinkpb.Keyset_Key{privKey},
174	}
175	privHandleWithoutPrimary, err := testkeyset.NewHandle(privKeysetWithoutPrimary)
176	if err != nil {
177		t.Fatalf("testkeyset.NewHandle(privKeysetWithoutPrimary) err = %v, want nil", err)
178	}
179	pubHandleWithoutPrimary, err := privHandleWithoutPrimary.Public()
180	if err != nil {
181		t.Fatalf("privateHandleWithoutPrimary.Public() err = %v, want nil", err)
182	}
183
184	if _, err = hybrid.NewHybridEncrypt(pubHandleWithoutPrimary); err == nil {
185		t.Errorf("NewHybridEncrypt(pubHandleWithoutPrimary) err = nil, want not nil")
186	}
187
188	if _, err = hybrid.NewHybridDecrypt(privHandleWithoutPrimary); err == nil {
189		t.Errorf("NewHybridDecrypt(privHandleWithoutPrimary) err = nil, want not nil")
190	}
191}
192
193func TestPrimitiveFactoryMonitoringWithAnnotationsLogsEncryptAndDecryptWithPrefix(t *testing.T) {
194	defer internalregistry.ClearMonitoringClient()
195	client := fakemonitoring.NewClient("fake-client")
196	if err := internalregistry.RegisterMonitoringClient(client); err != nil {
197		t.Fatalf("registry.RegisterMonitoringClient() err = %v, want nil", err)
198	}
199	handle, err := keyset.NewHandle(hybrid.DHKEM_X25519_HKDF_SHA256_HKDF_SHA256_AES_128_GCM_Key_Template())
200	if err != nil {
201		t.Fatalf("keyset.NewHandle() err = %v, want nil", err)
202	}
203	buff := &bytes.Buffer{}
204	if err := insecurecleartextkeyset.Write(handle, keyset.NewBinaryWriter(buff)); err != nil {
205		t.Fatalf("insecurecleartextkeyset.Write() err = %v, want nil", err)
206	}
207	annotations := map[string]string{"foo": "bar"}
208	privHandle, err := insecurecleartextkeyset.Read(keyset.NewBinaryReader(buff), keyset.WithAnnotations(annotations))
209	if err != nil {
210		t.Fatalf("insecurecleartextkeyset.Read() err = %v, want nil", err)
211	}
212	pubHandle, err := privHandle.Public()
213	if err != nil {
214		t.Fatalf("privHandle.Public() err = %v, want nil", err)
215	}
216	buff.Reset()
217	if err := insecurecleartextkeyset.Write(pubHandle, keyset.NewBinaryWriter(buff)); err != nil {
218		t.Fatalf("insecurecleartextkeyset.Write() err = %v, want nil", err)
219	}
220	pubHandle, err = insecurecleartextkeyset.Read(keyset.NewBinaryReader(buff), keyset.WithAnnotations(annotations))
221	if err != nil {
222		t.Fatalf("insecurecleartextkeyset.Read() err = %v, want nil", err)
223	}
224	e, err := hybrid.NewHybridEncrypt(pubHandle)
225	if err != nil {
226		t.Fatalf("hybrid.NewHybridEncrypt() err = %v, want nil", err)
227	}
228	d, err := hybrid.NewHybridDecrypt(privHandle)
229	if err != nil {
230		t.Fatalf("hybrid.NewHybridDecrypt() err = %v, want nil", err)
231	}
232	data := []byte("some_secret_piece_of_data")
233	aad := []byte("some_non_secret_piece_of_data")
234	ct, err := e.Encrypt(data, aad)
235	if err != nil {
236		t.Fatalf("e.Encrypt() err = %v, want nil", err)
237	}
238	if _, err := d.Decrypt(ct, aad); err != nil {
239		t.Fatalf("d.Decrypt() err = %v, want nil", err)
240	}
241	got := client.Events()
242	wantEncryptKeysetInfo := &monitoring.KeysetInfo{
243		Annotations:  annotations,
244		PrimaryKeyID: privHandle.KeysetInfo().GetPrimaryKeyId(),
245		Entries: []*monitoring.Entry{
246			{
247				KeyID:     pubHandle.KeysetInfo().GetPrimaryKeyId(),
248				Status:    monitoring.Enabled,
249				KeyType:   "tink.HpkePublicKey",
250				KeyPrefix: "TINK",
251			},
252		},
253	}
254	wantDecryptKeysetInfo := &monitoring.KeysetInfo{
255		Annotations:  annotations,
256		PrimaryKeyID: privHandle.KeysetInfo().GetPrimaryKeyId(),
257		Entries: []*monitoring.Entry{
258			{
259				KeyID:     privHandle.KeysetInfo().GetPrimaryKeyId(),
260				Status:    monitoring.Enabled,
261				KeyType:   "tink.HpkePrivateKey",
262				KeyPrefix: "TINK",
263			},
264		},
265	}
266	want := []*fakemonitoring.LogEvent{
267		{
268			Context:  monitoring.NewContext("hybrid_encrypt", "encrypt", wantEncryptKeysetInfo),
269			KeyID:    privHandle.KeysetInfo().GetPrimaryKeyId(),
270			NumBytes: len(data),
271		},
272		{
273			Context: monitoring.NewContext("hybrid_decrypt", "decrypt", wantDecryptKeysetInfo),
274			KeyID:   privHandle.KeysetInfo().GetPrimaryKeyId(),
275			// ciphertext was encrypted with a key that has a TINK output prefix. This adds a
276			// 5-byte prefix to the ciphertext. This prefix is not included in the `Log` call.
277			NumBytes: len(ct) - cryptofmt.NonRawPrefixSize,
278		},
279	}
280	if diff := cmp.Diff(want, got); diff != "" {
281		t.Errorf("%v", diff)
282	}
283}
284
285func TestPrimitiveFactoryMonitoringWithAnnotationsLogsEncryptAndDecryptWithoutPrefix(t *testing.T) {
286	defer internalregistry.ClearMonitoringClient()
287	client := fakemonitoring.NewClient("fake-client")
288	if err := internalregistry.RegisterMonitoringClient(client); err != nil {
289		t.Fatalf("registry.RegisterMonitoringClient() err = %v, want nil", err)
290	}
291	handle, err := keyset.NewHandle(hybrid.DHKEM_X25519_HKDF_SHA256_HKDF_SHA256_AES_128_GCM_Raw_Key_Template())
292	if err != nil {
293		t.Fatalf("keyset.NewHandle() err = %v, want nil", err)
294	}
295	buff := &bytes.Buffer{}
296	if err := insecurecleartextkeyset.Write(handle, keyset.NewBinaryWriter(buff)); err != nil {
297		t.Fatalf("insecurecleartextkeyset.Write() err = %v, want nil", err)
298	}
299	annotations := map[string]string{"foo": "bar"}
300	privHandle, err := insecurecleartextkeyset.Read(keyset.NewBinaryReader(buff), keyset.WithAnnotations(annotations))
301	if err != nil {
302		t.Fatalf("insecurecleartextkeyset.Read() err = %v, want nil", err)
303	}
304	pubHandle, err := privHandle.Public()
305	if err != nil {
306		t.Fatalf("privHandle.Public() err = %v, want nil", err)
307	}
308	buff.Reset()
309	if err := insecurecleartextkeyset.Write(pubHandle, keyset.NewBinaryWriter(buff)); err != nil {
310		t.Fatalf("insecurecleartextkeyset.Write() err = %v, want nil", err)
311	}
312	pubHandle, err = insecurecleartextkeyset.Read(keyset.NewBinaryReader(buff), keyset.WithAnnotations(annotations))
313	if err != nil {
314		t.Fatalf("insecurecleartextkeyset.Read() err = %v, want nil", err)
315	}
316	e, err := hybrid.NewHybridEncrypt(pubHandle)
317	if err != nil {
318		t.Fatalf("hybrid.NewHybridEncrypt() err = %v, want nil", err)
319	}
320	d, err := hybrid.NewHybridDecrypt(privHandle)
321	if err != nil {
322		t.Fatalf("hybrid.NewHybridDecrypt() err = %v, want nil", err)
323	}
324	data := []byte("some_secret_piece_of_data")
325	aad := []byte("some_non_secret_piece_of_data")
326	ct, err := e.Encrypt(data, aad)
327	if err != nil {
328		t.Fatalf("e.Encrypt() err = %v, want nil", err)
329	}
330	if _, err := d.Decrypt(ct, aad); err != nil {
331		t.Fatalf("d.Decrypt() err = %v, want nil", err)
332	}
333	got := client.Events()
334	wantEncryptKeysetInfo := &monitoring.KeysetInfo{
335		Annotations:  annotations,
336		PrimaryKeyID: privHandle.KeysetInfo().GetPrimaryKeyId(),
337		Entries: []*monitoring.Entry{
338			{
339				KeyID:     pubHandle.KeysetInfo().GetPrimaryKeyId(),
340				Status:    monitoring.Enabled,
341				KeyType:   "tink.HpkePublicKey",
342				KeyPrefix: "RAW",
343			},
344		},
345	}
346	wantDecryptKeysetInfo := &monitoring.KeysetInfo{
347		Annotations:  annotations,
348		PrimaryKeyID: privHandle.KeysetInfo().GetPrimaryKeyId(),
349		Entries: []*monitoring.Entry{
350			{
351				KeyID:     privHandle.KeysetInfo().GetPrimaryKeyId(),
352				Status:    monitoring.Enabled,
353				KeyType:   "tink.HpkePrivateKey",
354				KeyPrefix: "RAW",
355			},
356		},
357	}
358	want := []*fakemonitoring.LogEvent{
359		{
360			Context:  monitoring.NewContext("hybrid_encrypt", "encrypt", wantEncryptKeysetInfo),
361			KeyID:    pubHandle.KeysetInfo().GetPrimaryKeyId(),
362			NumBytes: len(data),
363		},
364		{
365			Context:  monitoring.NewContext("hybrid_decrypt", "decrypt", wantDecryptKeysetInfo),
366			KeyID:    privHandle.KeysetInfo().GetPrimaryKeyId(),
367			NumBytes: len(ct),
368		},
369	}
370	if diff := cmp.Diff(want, got); diff != "" {
371		t.Errorf("%v", diff)
372	}
373}
374
375func TestPrimitiveFactoryWithMonitoringWithMultipleKeysLogsEncryptionDecryption(t *testing.T) {
376	defer internalregistry.ClearMonitoringClient()
377	client := fakemonitoring.NewClient("fake-client")
378	if err := internalregistry.RegisterMonitoringClient(client); err != nil {
379		t.Fatalf("internalregistry.RegisterMonitoringClient() err = %v, want nil", err)
380	}
381	manager := keyset.NewManager()
382	templates := []*tinkpb.KeyTemplate{
383		hybrid.DHKEM_X25519_HKDF_SHA256_HKDF_SHA256_AES_128_GCM_Key_Template(),
384		hybrid.DHKEM_X25519_HKDF_SHA256_HKDF_SHA256_AES_256_GCM_Raw_Key_Template(),
385		hybrid.DHKEM_X25519_HKDF_SHA256_HKDF_SHA256_CHACHA20_POLY1305_Key_Template(),
386		hybrid.ECIESHKDFAES128GCMKeyTemplate(),
387	}
388	keyIDs := make([]uint32, 4, 4)
389	var err error
390	for i, tm := range templates {
391		keyIDs[i], err = manager.Add(tm)
392		if err != nil {
393			t.Fatalf("manager.Add() err = %v, want nil", err)
394		}
395	}
396	if err := manager.SetPrimary(keyIDs[1]); err != nil {
397		t.Fatalf("manager.SetPrimary(%d) err = %v, want nil", keyIDs[1], err)
398	}
399	if err := manager.Disable(keyIDs[0]); err != nil {
400		t.Fatalf("manager.Disable(%d) err = %v, want nil", keyIDs[0], err)
401	}
402	handle, err := manager.Handle()
403	if err != nil {
404		t.Fatalf("manager.Handle() err = %v, want nil", err)
405	}
406	buff := &bytes.Buffer{}
407	if err := insecurecleartextkeyset.Write(handle, keyset.NewBinaryWriter(buff)); err != nil {
408		t.Fatalf("insecurecleartextkeyset.Write() err = %v, want nil", err)
409	}
410	annotations := map[string]string{"foo": "bar"}
411	privHandle, err := insecurecleartextkeyset.Read(keyset.NewBinaryReader(buff), keyset.WithAnnotations(annotations))
412	if err != nil {
413		t.Fatalf("insecurecleartextkeyset.Read() err = %v, want nil", err)
414	}
415	pubHandle, err := privHandle.Public()
416	if err != nil {
417		t.Fatalf("privHandle.Public() err = %v, want nil", err)
418	}
419	buff.Reset()
420	if err := insecurecleartextkeyset.Write(pubHandle, keyset.NewBinaryWriter(buff)); err != nil {
421		t.Fatalf("insecurecleartextkeyset.Write() err = %v, want nil", err)
422	}
423	pubHandle, err = insecurecleartextkeyset.Read(keyset.NewBinaryReader(buff), keyset.WithAnnotations(annotations))
424	if err != nil {
425		t.Fatalf("insecurecleartextkeyset.Read() err = %v, want nil", err)
426	}
427	e, err := hybrid.NewHybridEncrypt(pubHandle)
428	if err != nil {
429		t.Fatalf("hybrid.NewHybridEncrypt() err = %v, want nil", err)
430	}
431	d, err := hybrid.NewHybridDecrypt(privHandle)
432	if err != nil {
433		t.Fatalf("hybrid.NewHybridDecrypt() err = %v, want nil", err)
434	}
435	data := []byte("some_secret_piece_of_data")
436	aad := []byte("some_non_secret_piece_of_data")
437	ct, err := e.Encrypt(data, aad)
438	if err != nil {
439		t.Fatalf("e.Encrypt() err = %v, want nil", err)
440	}
441	if _, err := d.Decrypt(ct, aad); err != nil {
442		t.Fatalf("d.Decrypt() err = %v, want nil", err)
443	}
444	failures := len(client.Failures())
445	if failures != 0 {
446		t.Errorf("len(client.Failures()) = %d, want 0", failures)
447	}
448	got := client.Events()
449	wantEncryptKeysetInfo := &monitoring.KeysetInfo{
450		Annotations:  annotations,
451		PrimaryKeyID: privHandle.KeysetInfo().GetPrimaryKeyId(),
452		Entries: []*monitoring.Entry{
453			{
454				KeyID:     pubHandle.KeysetInfo().GetPrimaryKeyId(),
455				Status:    monitoring.Enabled,
456				KeyType:   "tink.HpkePublicKey",
457				KeyPrefix: "RAW",
458			},
459			{
460				KeyID:     keyIDs[2],
461				Status:    monitoring.Enabled,
462				KeyType:   "tink.HpkePublicKey",
463				KeyPrefix: "TINK",
464			},
465			{
466				KeyID:     keyIDs[3],
467				Status:    monitoring.Enabled,
468				KeyType:   "tink.EciesAeadHkdfPublicKey",
469				KeyPrefix: "TINK",
470			},
471		},
472	}
473	wantDecryptKeysetInfo := &monitoring.KeysetInfo{
474		Annotations:  annotations,
475		PrimaryKeyID: privHandle.KeysetInfo().GetPrimaryKeyId(),
476		Entries: []*monitoring.Entry{
477			{
478				KeyID:     privHandle.KeysetInfo().GetPrimaryKeyId(),
479				Status:    monitoring.Enabled,
480				KeyType:   "tink.HpkePrivateKey",
481				KeyPrefix: "RAW",
482			},
483			{
484				KeyID:     keyIDs[2],
485				Status:    monitoring.Enabled,
486				KeyType:   "tink.HpkePrivateKey",
487				KeyPrefix: "TINK",
488			},
489			{
490				KeyID:     keyIDs[3],
491				Status:    monitoring.Enabled,
492				KeyType:   "tink.EciesAeadHkdfPrivateKey",
493				KeyPrefix: "TINK",
494			},
495		},
496	}
497	want := []*fakemonitoring.LogEvent{
498		{
499			Context:  monitoring.NewContext("hybrid_encrypt", "encrypt", wantEncryptKeysetInfo),
500			KeyID:    privHandle.KeysetInfo().GetPrimaryKeyId(),
501			NumBytes: len(data),
502		},
503		{
504			Context:  monitoring.NewContext("hybrid_decrypt", "decrypt", wantDecryptKeysetInfo),
505			KeyID:    privHandle.KeysetInfo().GetPrimaryKeyId(),
506			NumBytes: len(ct),
507		},
508	}
509	// sort by keyID to avoid non deterministic order.
510	entryLessFunc := func(a, b *monitoring.Entry) bool {
511		return a.KeyID < b.KeyID
512	}
513	if diff := cmp.Diff(want, got, cmpopts.SortSlices(entryLessFunc)); diff != "" {
514		t.Errorf("%v", diff)
515	}
516}
517
518func TestPrimitiveFactoryMonitoringWithAnnotationsEncryptFailureIsLogged(t *testing.T) {
519	defer internalregistry.ClearMonitoringClient()
520	client := fakemonitoring.NewClient("fake-client")
521	if err := internalregistry.RegisterMonitoringClient(client); err != nil {
522		t.Fatalf("internalregistry.RegisterMonitoringClient() err = %v, want nil", err)
523	}
524
525	handle, err := keyset.NewHandle(hybrid.DHKEM_X25519_HKDF_SHA256_HKDF_SHA256_AES_128_GCM_Key_Template())
526	if err != nil {
527		t.Fatalf("keyset.NewHandle() err = %v, want nil", err)
528	}
529	buff := &bytes.Buffer{}
530	if err := insecurecleartextkeyset.Write(handle, keyset.NewBinaryWriter(buff)); err != nil {
531		t.Fatalf("insecurecleartextkeyset.Write() err = %v, want nil", err)
532	}
533	annotations := map[string]string{"foo": "bar"}
534	privHandle, err := insecurecleartextkeyset.Read(keyset.NewBinaryReader(buff), keyset.WithAnnotations(annotations))
535	if err != nil {
536		t.Fatalf("insecurecleartextkeyset.Read() err = %v, want nil", err)
537	}
538	buff.Reset()
539
540	pubHandle, err := privHandle.Public()
541	if err != nil {
542		t.Fatalf("privHandle.Public() err = %v, want nil", err)
543	}
544	if err := insecurecleartextkeyset.Write(pubHandle, keyset.NewBinaryWriter(buff)); err != nil {
545		t.Fatalf("insecurecleartextkeyset.Write() err = %v, want nil", err)
546	}
547	pubHandle, err = insecurecleartextkeyset.Read(keyset.NewBinaryReader(buff), keyset.WithAnnotations(annotations))
548	if err != nil {
549		t.Fatalf("insecurecleartextkeyset.Read() err = %v, want nil", err)
550	}
551
552	e, err := hybrid.NewHybridEncrypt(pubHandle)
553	if err != nil {
554		t.Fatalf("NewHybridEncrypt() err = %v, want nil", err)
555	}
556	d, err := hybrid.NewHybridDecrypt(privHandle)
557	if err != nil {
558		t.Fatalf("NewHybridDecrypt() err = %v, want nil", err)
559	}
560
561	ct, err := e.Encrypt([]byte("plaintext"), []byte("info"))
562	if err != nil {
563		t.Fatalf("Encrypt() err = nil, want non-nil")
564	}
565	if _, err := d.Decrypt(ct, []byte("wrong info")); err == nil {
566		t.Fatalf("Decrypt() err = nil, want non-nil")
567	}
568
569	got := client.Failures()
570	primaryKeyID := privHandle.KeysetInfo().GetPrimaryKeyId()
571	want := []*fakemonitoring.LogFailure{
572		{
573			Context: monitoring.NewContext(
574				"hybrid_decrypt",
575				"decrypt",
576				monitoring.NewKeysetInfo(
577					annotations,
578					primaryKeyID,
579					[]*monitoring.Entry{
580						{
581							KeyID:     primaryKeyID,
582							Status:    monitoring.Enabled,
583							KeyType:   "tink.HpkePrivateKey",
584							KeyPrefix: "TINK",
585						},
586					},
587				),
588			),
589		},
590	}
591	if diff := cmp.Diff(want, got); diff != "" {
592		t.Errorf("%v", diff)
593	}
594}
595
596func TestPrimitiveFactoryMonitoringWithAnnotationsDecryptFailureIsLogged(t *testing.T) {
597	defer internalregistry.ClearMonitoringClient()
598	client := fakemonitoring.NewClient("fake-client")
599	if err := internalregistry.RegisterMonitoringClient(client); err != nil {
600		t.Fatalf("registry.RegisterMonitoringClient() err = %v, want nil", err)
601	}
602	handle, err := keyset.NewHandle(hybrid.DHKEM_X25519_HKDF_SHA256_HKDF_SHA256_AES_128_GCM_Key_Template())
603	if err != nil {
604		t.Fatalf("keyset.NewHandle() err = %v, want nil", err)
605	}
606	buff := &bytes.Buffer{}
607	if err := insecurecleartextkeyset.Write(handle, keyset.NewBinaryWriter(buff)); err != nil {
608		t.Fatalf("insecurecleartextkeyset.Write() err = %v, want nil", err)
609	}
610	annotations := map[string]string{"foo": "bar"}
611	privHandle, err := insecurecleartextkeyset.Read(keyset.NewBinaryReader(buff), keyset.WithAnnotations(annotations))
612	if err != nil {
613		t.Fatalf("insecurecleartextkeyset.Read() err = %v, want nil", err)
614	}
615	e, err := hybrid.NewHybridDecrypt(privHandle)
616	if err != nil {
617		t.Fatalf("hybrid.NewHybridDecrypt() err = %v, want nil", err)
618	}
619	if _, err := e.Decrypt([]byte("invalid_data"), nil); err == nil {
620		t.Fatalf("e.Decrypt() err = nil, want non-nil error")
621	}
622	got := client.Failures()
623	want := []*fakemonitoring.LogFailure{
624		{
625			Context: monitoring.NewContext(
626				"hybrid_decrypt",
627				"decrypt",
628				monitoring.NewKeysetInfo(
629					annotations,
630					privHandle.KeysetInfo().GetPrimaryKeyId(),
631					[]*monitoring.Entry{
632						{
633							KeyID:     privHandle.KeysetInfo().GetPrimaryKeyId(),
634							Status:    monitoring.Enabled,
635							KeyType:   "tink.HpkePrivateKey",
636							KeyPrefix: "TINK",
637						},
638					},
639				),
640			),
641		},
642	}
643	if diff := cmp.Diff(want, got); diff != "" {
644		t.Errorf("%v", diff)
645	}
646}
647
648func TestPrimitiveFactoryEncryptDecryptWithoutAnnotationsDoesNotMonitor(t *testing.T) {
649	defer internalregistry.ClearMonitoringClient()
650	client := fakemonitoring.NewClient("fake-client")
651	if err := internalregistry.RegisterMonitoringClient(client); err != nil {
652		t.Fatalf("registry.RegisterMonitoringClient() err = %v, want nil", err)
653	}
654	privHandle, err := keyset.NewHandle(hybrid.DHKEM_X25519_HKDF_SHA256_HKDF_SHA256_AES_128_GCM_Key_Template())
655	if err != nil {
656		t.Fatalf("keyset.NewHandle() err = %v, want nil", err)
657	}
658	pubHandle, err := privHandle.Public()
659	if err != nil {
660		t.Fatalf("privHandle.Public() err = %v, want nil", err)
661	}
662	e, err := hybrid.NewHybridEncrypt(pubHandle)
663	if err != nil {
664		t.Fatalf("hybrid.NewHybridEncrypt() err = %v, want nil", err)
665	}
666	d, err := hybrid.NewHybridDecrypt(privHandle)
667	if err != nil {
668		t.Fatalf("hybrid.NewHybridDecrypt() err = %v, want nil", err)
669	}
670	data := []byte("some_secret_piece_of_data")
671	aad := []byte("some_non_secret_piece_of_data")
672	ct, err := e.Encrypt(data, aad)
673	if err != nil {
674		t.Fatalf("e.Encrypt() err = %v, want nil", err)
675	}
676	if _, err := d.Decrypt(ct, aad); err != nil {
677		t.Fatalf("d.Decrypt() err = %v, want nil", err)
678	}
679	if len(client.Events()) != 0 {
680		t.Errorf("len(client.Events()) = %d, want 0", len(client.Events()))
681	}
682	if len(client.Failures()) != 0 {
683		t.Errorf("len(client.Failures()) = %d, want 0", len(client.Failures()))
684	}
685}
686
687// Since the HybridEncrypt interface is a subset of the AEAD interface, verify
688// that a HybridEncrypt primitive cannot be obtained from a keyset handle
689// containing an AEAD key.
690func TestEncryptFactoryFailsOnAEADHandle(t *testing.T) {
691	handle, err := keyset.NewHandle(hybrid.DHKEM_X25519_HKDF_SHA256_HKDF_SHA256_AES_128_GCM_Key_Template())
692	if err != nil {
693		t.Fatalf("keyset.NewHandle gives err = '%v', want nil", err)
694	}
695	pub, err := handle.Public()
696	if err != nil {
697		t.Fatalf("handle.Public gives err = '%v', want nil", err)
698	}
699	manager := keyset.NewManagerFromHandle(pub)
700	_, err = manager.Add(aead.AES128GCMKeyTemplate())
701	if err != nil {
702		t.Fatalf("manager.Add gives err = '%v', want nil", err)
703	}
704	mixedHandle, err := manager.Handle()
705	if err != nil {
706		t.Fatalf("manager.Handle gives err = '%v', want nil", err)
707	}
708	if _, err := hybrid.NewHybridEncrypt(mixedHandle); err == nil {
709		t.Error("hybrid.NewHybridDecrypt err = nil, want err")
710	}
711}
712
713// Similar to the above but for HybridDecrypt.
714func TestDecryptFactoryFailsOnAEADHandle(t *testing.T) {
715	manager := keyset.NewManager()
716	id, err := manager.Add(aead.AES256GCMKeyTemplate())
717	if err != nil {
718		t.Fatalf("manager.Add gives err = '%v', want nil", err)
719	}
720	err = manager.SetPrimary(id)
721	if err != nil {
722		t.Fatalf("manager.SetPrimary gives err = '%v', want nil", err)
723	}
724	_, err = manager.Add(hybrid.DHKEM_X25519_HKDF_SHA256_HKDF_SHA256_AES_128_GCM_Key_Template())
725	if err != nil {
726		t.Fatalf("manager.Add gives err = '%v', want nil", err)
727	}
728	handle, err := manager.Handle()
729	if err != nil {
730		t.Fatalf("manager.Handle gives err = '%v', want nil", err)
731	}
732
733	if _, err := hybrid.NewHybridDecrypt(handle); err == nil {
734		t.Error("hybrid.NewHybridDecrypt err = nil, want err")
735	}
736}
737