xref: /aosp_15_r20/external/tink/go/keyderivation/internal/streamingprf/streaming_prf_factory_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 streamingprf_test
18
19import (
20	"bytes"
21	"testing"
22
23	"google.golang.org/protobuf/proto"
24	"github.com/google/tink/go/aead"
25	"github.com/google/tink/go/core/registry"
26	"github.com/google/tink/go/keyderivation/internal/streamingprf"
27	"github.com/google/tink/go/keyset"
28	"github.com/google/tink/go/prf"
29	"github.com/google/tink/go/subtle/random"
30	"github.com/google/tink/go/testkeyset"
31	commonpb "github.com/google/tink/go/proto/common_go_proto"
32	hkdfpb "github.com/google/tink/go/proto/hkdf_prf_go_proto"
33	tinkpb "github.com/google/tink/go/proto/tink_go_proto"
34)
35
36func TestNew(t *testing.T) {
37	keyData, err := registry.NewKeyData(prf.HKDFSHA256PRFKeyTemplate())
38	if err != nil {
39		t.Fatalf("registry.NewKeyData() err = %v", err)
40	}
41	ks := &tinkpb.Keyset{
42		PrimaryKeyId: 119,
43		Key: []*tinkpb.Keyset_Key{
44			&tinkpb.Keyset_Key{
45				KeyData:          keyData,
46				Status:           tinkpb.KeyStatusType_ENABLED,
47				KeyId:            119,
48				OutputPrefixType: tinkpb.OutputPrefixType_RAW,
49			},
50		},
51	}
52	handle, err := testkeyset.NewHandle(ks)
53	if err != nil {
54		t.Fatalf("testkeyset.NewHandle(ks) err = %v, want nil", err)
55	}
56	prf, err := streamingprf.New(handle)
57	if err != nil {
58		t.Fatalf("streamingprf.New() err = %v, want nil", err)
59	}
60	r, err := prf.Compute(random.GetRandomBytes(32))
61	if err != nil {
62		t.Fatalf("prf.Compute() err = %v, want nil", err)
63	}
64	limit := limitFromHash(t, commonpb.HashType_SHA256)
65	out := make([]byte, limit)
66	n, err := r.Read(out)
67	if n != limit || err != nil {
68		t.Errorf("Read() bytes = %d, want %d: %v", n, limit, err)
69	}
70}
71
72func TestNewEqualToStreamingPRFPrimitive(t *testing.T) {
73	streamingPRFKM := streamingprf.HKDFStreamingPRFKeyManager{}
74	prfKM, err := registry.GetKeyManager(hkdfPRFTypeURL)
75	if err != nil {
76		t.Fatalf("GetKeyManager(%s) err = %v, want nil", hkdfPRFTypeURL, err)
77	}
78	for _, test := range []struct {
79		name string
80		hash commonpb.HashType
81		salt []byte
82	}{
83		{
84			name: "SHA256_nil_salt",
85			hash: commonpb.HashType_SHA256,
86		},
87		{
88			name: "SHA256_random_salt",
89			hash: commonpb.HashType_SHA256,
90			salt: random.GetRandomBytes(16),
91		},
92		{
93			name: "SHA512_nil_salt",
94			hash: commonpb.HashType_SHA512,
95		},
96		{
97			name: "SHA512_random_salt",
98			hash: commonpb.HashType_SHA512,
99			salt: random.GetRandomBytes(16),
100		},
101	} {
102		t.Run(test.name, func(t *testing.T) {
103			// Construct shared key data.
104			keyFormat := &hkdfpb.HkdfPrfKeyFormat{
105				Params: &hkdfpb.HkdfPrfParams{
106					Hash: test.hash,
107					Salt: test.salt,
108				},
109				KeySize: 32,
110				Version: 0,
111			}
112			serializedKeyFormat, err := proto.Marshal(keyFormat)
113			if err != nil {
114				t.Fatalf("proto.Marshal(%v) err = %v, want nil", keyFormat, err)
115			}
116			sharedKeyData, err := prfKM.NewKeyData(serializedKeyFormat)
117			if err != nil {
118				t.Fatalf("NewKeyData() err = %v, want nil", err)
119			}
120
121			// Use shared key data to create StreamingPRF using New().
122			var primaryKeyID uint32 = 12
123			handle, err := testkeyset.NewHandle(
124				&tinkpb.Keyset{
125					PrimaryKeyId: primaryKeyID,
126					Key: []*tinkpb.Keyset_Key{
127						&tinkpb.Keyset_Key{
128							KeyData:          sharedKeyData,
129							Status:           tinkpb.KeyStatusType_ENABLED,
130							KeyId:            primaryKeyID,
131							OutputPrefixType: tinkpb.OutputPrefixType_RAW,
132						},
133					},
134				})
135			if err != nil {
136				t.Fatalf("testkeyset.NewHandle() err = %v, want nil", err)
137			}
138			gotPRF, err := streamingprf.New(handle)
139			if err != nil {
140				t.Fatalf("streamingprf.New() err = %v, want nil", err)
141			}
142
143			// Use shared key data to create StreamingPRF using Primitive().
144			p, err := streamingPRFKM.Primitive(sharedKeyData.GetValue())
145			if err != nil {
146				t.Fatalf("Primitive() err = %v, want nil", err)
147			}
148			wantPRF, ok := p.(streamingprf.StreamingPRF)
149			if !ok {
150				t.Fatal("primitive is not StreamingPRF")
151			}
152
153			// Verify both PRFs return the same results.
154			limit := limitFromHash(t, test.hash)
155			got, want := make([]byte, limit), make([]byte, limit)
156			data := random.GetRandomBytes(32)
157			{
158				r, err := gotPRF.Compute(data)
159				if err != nil {
160					t.Fatalf("Compute() err = %v, want nil", err)
161				}
162				n, err := r.Read(got)
163				if n != limit || err != nil {
164					t.Fatalf("Read() bytes = %d, want %d: %v", n, limit, err)
165				}
166			}
167			{
168				r, err := wantPRF.Compute(data)
169				if err != nil {
170					t.Fatalf("Compute() err = %v, want nil", err)
171				}
172				n, err := r.Read(want)
173				if n != limit || err != nil {
174					t.Fatalf("Read() bytes = %d, want %d: %v", n, limit, err)
175				}
176			}
177			if !bytes.Equal(got, want) {
178				t.Errorf("Read() = %v, want %v", got, want)
179			}
180		})
181	}
182}
183
184func TestNewRejectsIncorrectKeysetHandle(t *testing.T) {
185	if _, err := streamingprf.New(nil); err == nil {
186		t.Error("streamingprf.New() err = nil, want non-nil")
187	}
188
189	aeadHandle, err := keyset.NewHandle(aead.AES128GCMKeyTemplate())
190	if err != nil {
191		t.Fatalf("keyset.NewHandle() err = %v, want nil", err)
192	}
193	if _, err := streamingprf.New(aeadHandle); err == nil {
194		t.Error("streamingprf.New() err = nil, want non-nil")
195	}
196}
197
198func TestNewRejectsInvalidKeysetHandle(t *testing.T) {
199	keyData, err := registry.NewKeyData(prf.HKDFSHA256PRFKeyTemplate())
200	if err != nil {
201		t.Fatalf("registry.NewKeyData() err = %v", err)
202	}
203	for _, test := range []struct {
204		name   string
205		keyset *tinkpb.Keyset
206	}{
207		{
208			"multiple raw keys",
209			&tinkpb.Keyset{
210				PrimaryKeyId: 119,
211				Key: []*tinkpb.Keyset_Key{
212					&tinkpb.Keyset_Key{
213						KeyData:          keyData,
214						Status:           tinkpb.KeyStatusType_ENABLED,
215						KeyId:            119,
216						OutputPrefixType: tinkpb.OutputPrefixType_RAW,
217					},
218					&tinkpb.Keyset_Key{
219						KeyData:          keyData,
220						Status:           tinkpb.KeyStatusType_ENABLED,
221						KeyId:            200,
222						OutputPrefixType: tinkpb.OutputPrefixType_RAW,
223					},
224				},
225			},
226		},
227		{
228			"various output prefix keys",
229			&tinkpb.Keyset{
230				PrimaryKeyId: 119,
231				Key: []*tinkpb.Keyset_Key{
232					&tinkpb.Keyset_Key{
233						KeyData:          keyData,
234						Status:           tinkpb.KeyStatusType_ENABLED,
235						KeyId:            119,
236						OutputPrefixType: tinkpb.OutputPrefixType_RAW,
237					},
238					&tinkpb.Keyset_Key{
239						KeyData:          keyData,
240						Status:           tinkpb.KeyStatusType_ENABLED,
241						KeyId:            200,
242						OutputPrefixType: tinkpb.OutputPrefixType_TINK,
243					},
244				},
245			},
246		},
247		{
248			"invalid prefix type",
249			&tinkpb.Keyset{
250				PrimaryKeyId: 119,
251				Key: []*tinkpb.Keyset_Key{
252					&tinkpb.Keyset_Key{
253						KeyData:          keyData,
254						Status:           tinkpb.KeyStatusType_ENABLED,
255						KeyId:            119,
256						OutputPrefixType: tinkpb.OutputPrefixType_TINK,
257					},
258				},
259			}},
260		{
261			"invalid status",
262			&tinkpb.Keyset{
263				PrimaryKeyId: 119,
264				Key: []*tinkpb.Keyset_Key{
265					&tinkpb.Keyset_Key{
266						KeyData:          keyData,
267						Status:           tinkpb.KeyStatusType_UNKNOWN_STATUS,
268						KeyId:            119,
269						OutputPrefixType: tinkpb.OutputPrefixType_RAW,
270					},
271				},
272			},
273		},
274		{
275			"no primary key",
276			&tinkpb.Keyset{
277				PrimaryKeyId: 200,
278				Key: []*tinkpb.Keyset_Key{
279					&tinkpb.Keyset_Key{
280						KeyData:          keyData,
281						Status:           tinkpb.KeyStatusType_UNKNOWN_STATUS,
282						KeyId:            119,
283						OutputPrefixType: tinkpb.OutputPrefixType_RAW,
284					},
285				},
286			},
287		},
288	} {
289		t.Run(test.name, func(t *testing.T) {
290			handle, err := testkeyset.NewHandle(test.keyset)
291			if err != nil {
292				t.Fatalf("testkeyset.NewHandle(test.keyset) err = %v, want nil", err)
293			}
294			if _, err := streamingprf.New(handle); err == nil {
295				t.Error("streamingprf.New() err = nil, want non-nil")
296			}
297		})
298	}
299}
300