xref: /aosp_15_r20/external/tink/go/hybrid/hpke_public_key_manager_test.go (revision e7b1675dde1b92d52ec075b0a92829627f2c52a5)
1// Copyright 2022 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
18
19import (
20	"bytes"
21	"testing"
22
23	"google.golang.org/protobuf/proto"
24	"github.com/google/tink/go/core/registry"
25	"github.com/google/tink/go/hybrid/internal/hpke"
26	"github.com/google/tink/go/subtle/random"
27	"github.com/google/tink/go/subtle"
28	hpkepb "github.com/google/tink/go/proto/hpke_go_proto"
29)
30
31var hpkeAEADs = []hpkepb.HpkeAead{
32	hpkepb.HpkeAead_AES_128_GCM,
33	hpkepb.HpkeAead_AES_256_GCM,
34	hpkepb.HpkeAead_CHACHA20_POLY1305,
35}
36
37func TestPublicKeyManagerPrimitiveRejectsInvalidKeyVersion(t *testing.T) {
38	km, err := registry.GetKeyManager(hpkePublicKeyTypeURL)
39	if err != nil {
40		t.Fatalf("GetKeyManager(%q) err = %v, want nil", hpkePublicKeyTypeURL, err)
41	}
42	params := &hpkepb.HpkeParams{
43		Kem:  hpkepb.HpkeKem_DHKEM_X25519_HKDF_SHA256,
44		Kdf:  hpkepb.HpkeKdf_HKDF_SHA256,
45		Aead: hpkepb.HpkeAead_AES_256_GCM,
46	}
47	pubKey, _ := pubPrivKeys(t, params)
48	pubKey.Version = 1
49	serializedPubKey, err := proto.Marshal(pubKey)
50	if err != nil {
51		t.Fatal(err)
52	}
53	if _, err := km.Primitive(serializedPubKey); err == nil {
54		t.Error("Primitive() err = nil, want error")
55	}
56}
57
58func TestPublicKeyManagerPrimitiveRejectsInvalidParams(t *testing.T) {
59	km, err := registry.GetKeyManager(hpkePublicKeyTypeURL)
60	if err != nil {
61		t.Fatalf("GetKeyManager(%q) err = %v, want nil", hpkePublicKeyTypeURL, err)
62	}
63
64	tests := []struct {
65		name   string
66		params *hpkepb.HpkeParams
67	}{
68		{"kem", &hpkepb.HpkeParams{
69			Kem:  hpkepb.HpkeKem_KEM_UNKNOWN,
70			Kdf:  hpkepb.HpkeKdf_HKDF_SHA256,
71			Aead: hpkepb.HpkeAead_AES_256_GCM,
72		}},
73		{"kdf", &hpkepb.HpkeParams{
74			Kem:  hpkepb.HpkeKem_DHKEM_X25519_HKDF_SHA256,
75			Kdf:  hpkepb.HpkeKdf_KDF_UNKNOWN,
76			Aead: hpkepb.HpkeAead_AES_256_GCM,
77		}},
78		{"aead", &hpkepb.HpkeParams{
79			Kem:  hpkepb.HpkeKem_DHKEM_X25519_HKDF_SHA256,
80			Kdf:  hpkepb.HpkeKdf_HKDF_SHA256,
81			Aead: hpkepb.HpkeAead_AEAD_UNKNOWN,
82		}},
83	}
84
85	for _, test := range tests {
86		t.Run(test.name, func(t *testing.T) {
87			serializedPubKey, _ := serializedPubPrivKeys(t, test.params)
88			if _, err := km.Primitive(serializedPubKey); err == nil {
89				t.Error("Primitive() err = nil, want error")
90			}
91		})
92	}
93}
94
95func TestPublicKeyManagerPrimitiveRejectsMissingParams(t *testing.T) {
96	km, err := registry.GetKeyManager(hpkePublicKeyTypeURL)
97	if err != nil {
98		t.Fatalf("GetKeyManager(%q) err = %v, want nil", hpkePublicKeyTypeURL, err)
99	}
100	serializedPubKey, _ := serializedPubPrivKeys(t, nil)
101	if _, err := km.Primitive(serializedPubKey); err == nil {
102		t.Error("Primitive() err = nil, want error")
103	}
104}
105
106func TestPublicKeyManagerPrimitiveRejectsNilKey(t *testing.T) {
107	km, err := registry.GetKeyManager(hpkePublicKeyTypeURL)
108	if err != nil {
109		t.Fatalf("GetKeyManager(%q) err = %v, want nil", hpkePublicKeyTypeURL, err)
110	}
111	if _, err := km.Primitive(nil); err == nil {
112		t.Error("Primitive() err = nil, want error")
113	}
114}
115
116func TestPublicKeyManagerPrimitiveEncryptDecrypt(t *testing.T) {
117	km, err := registry.GetKeyManager(hpkePublicKeyTypeURL)
118	if err != nil {
119		t.Fatalf("GetKeyManager(%q) err = %v, want nil", hpkePublicKeyTypeURL, err)
120	}
121
122	wantPT := random.GetRandomBytes(200)
123	ctxInfo := random.GetRandomBytes(100)
124
125	for _, aeadID := range hpkeAEADs {
126		params := &hpkepb.HpkeParams{
127			Kem:  hpkepb.HpkeKem_DHKEM_X25519_HKDF_SHA256,
128			Kdf:  hpkepb.HpkeKdf_HKDF_SHA256,
129			Aead: aeadID,
130		}
131		pubKey, privKey := pubPrivKeys(t, params)
132		serializedPubKey, err := proto.Marshal(pubKey)
133		if err != nil {
134			t.Fatal(err)
135		}
136
137		e, err := km.Primitive(serializedPubKey)
138		if err != nil {
139			t.Fatalf("Primitive() err = %v, want nil", err)
140		}
141		enc, ok := e.(*hpke.Encrypt)
142		if !ok {
143			t.Fatal("primitive is not Encrypt")
144		}
145		dec, err := hpke.NewDecrypt(privKey)
146		if err != nil {
147			t.Fatalf("hpke.NewDecrypt() err = %v, want nil", err)
148		}
149
150		ct, err := enc.Encrypt(wantPT, ctxInfo)
151		if err != nil {
152			t.Fatalf("Encrypt() err = %v, want nil", err)
153		}
154		gotPT, err := dec.Decrypt(ct, ctxInfo)
155		if err != nil {
156			t.Fatalf("Decrypt() err = %v, want nil", err)
157		}
158		if !bytes.Equal(gotPT, wantPT) {
159			t.Errorf("Decrypt() = %x, want %x", gotPT, wantPT)
160		}
161	}
162}
163
164func TestPublicKeyManagerDoesSupport(t *testing.T) {
165	km, err := registry.GetKeyManager(hpkePublicKeyTypeURL)
166	if err != nil {
167		t.Fatalf("GetKeyManager(%q) err = %v, want nil", hpkePublicKeyTypeURL, err)
168	}
169	if !km.DoesSupport(hpkePublicKeyTypeURL) {
170		t.Errorf("DoesSupport(%q) = false, want true", hpkePublicKeyTypeURL)
171	}
172	unsupportedKeyTypeURL := "unsupported.key.type"
173	if km.DoesSupport(unsupportedKeyTypeURL) {
174		t.Errorf("DoesSupport(%q) = true, want false", unsupportedKeyTypeURL)
175	}
176}
177
178func TestPublicKeyManagerTypeURL(t *testing.T) {
179	km, err := registry.GetKeyManager(hpkePublicKeyTypeURL)
180	if err != nil {
181		t.Fatalf("GetKeyManager(%q) err = %v, want nil", hpkePublicKeyTypeURL, err)
182	}
183	if km.TypeURL() != hpkePublicKeyTypeURL {
184		t.Errorf("TypeURL = %q, want %q", km.TypeURL(), hpkePublicKeyTypeURL)
185	}
186}
187
188func TestPublicKeyManagerNotSupported(t *testing.T) {
189	km, err := registry.GetKeyManager(hpkePublicKeyTypeURL)
190	if err != nil {
191		t.Fatalf("GetKeyManager(%q) err = %v, want nil", hpkePublicKeyTypeURL, err)
192	}
193	if _, err := km.NewKey(nil); err == nil {
194		t.Error("NewKey(nil) err = nil, want error")
195	}
196	if _, err := km.NewKeyData(nil); err == nil {
197		t.Error("NewKeyData(nil) err = nil, want error")
198	}
199}
200
201func serializedPubPrivKeys(t *testing.T, params *hpkepb.HpkeParams) ([]byte, []byte) {
202	t.Helper()
203	pub, priv := pubPrivKeys(t, params)
204	serializedPub, err := proto.Marshal(pub)
205	if err != nil {
206		t.Fatal(err)
207	}
208	serializedPriv, err := proto.Marshal(priv)
209	if err != nil {
210		t.Fatal(err)
211	}
212	return serializedPub, serializedPriv
213}
214
215func pubPrivKeys(t *testing.T, params *hpkepb.HpkeParams) (*hpkepb.HpkePublicKey, *hpkepb.HpkePrivateKey) {
216	t.Helper()
217
218	priv, err := subtle.GeneratePrivateKeyX25519()
219	if err != nil {
220		t.Fatalf("GeneratePrivateKeyX25519: err %q", err)
221	}
222	pub, err := subtle.PublicFromPrivateX25519(priv)
223	if err != nil {
224		t.Fatalf("PublicFromPrivateX25519: err %q", err)
225	}
226
227	pubKey := &hpkepb.HpkePublicKey{
228		Version:   0,
229		Params:    params,
230		PublicKey: pub,
231	}
232	privKey := &hpkepb.HpkePrivateKey{
233		Version:    0,
234		PublicKey:  pubKey,
235		PrivateKey: priv,
236	}
237	return pubKey, privKey
238}
239