xref: /aosp_15_r20/external/tink/go/streamingaead/aes_gcm_hkdf_key_manager_test.go (revision e7b1675dde1b92d52ec075b0a92829627f2c52a5)
1// Copyright 2020 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 streamingaead_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/streamingaead/subtle"
30	"github.com/google/tink/go/subtle/random"
31	"github.com/google/tink/go/testutil"
32	gcmhkdfpb "github.com/google/tink/go/proto/aes_gcm_hkdf_streaming_go_proto"
33	commonpb "github.com/google/tink/go/proto/common_go_proto"
34	tinkpb "github.com/google/tink/go/proto/tink_go_proto"
35)
36
37var aesGCMHKDFKeySizes = []uint32{16, 32}
38
39func TestAESGCMHKDFGetPrimitiveBasic(t *testing.T) {
40	keyManager, err := registry.GetKeyManager(testutil.AESGCMHKDFTypeURL)
41	if err != nil {
42		t.Errorf("cannot obtain AES-GCM-HKDF key manager: %s", err)
43	}
44	for _, keySize := range aesGCMHKDFKeySizes {
45		key := testutil.NewAESGCMHKDFKey(testutil.AESGCMHKDFKeyVersion, keySize, keySize, commonpb.HashType_SHA256, 4096)
46		serializedKey, err := proto.Marshal(key)
47		if err != nil {
48			t.Errorf("failed to marshal key: %s", err)
49		}
50		p, err := keyManager.Primitive(serializedKey)
51		if err != nil {
52			t.Errorf("unexpected error: %s", err)
53		}
54		if err := validatePrimitive(p, key); err != nil {
55			t.Errorf("%s", err)
56		}
57	}
58}
59
60func TestAESGCMHKDFGetPrimitiveWithInvalidInput(t *testing.T) {
61	keyManager, err := registry.GetKeyManager(testutil.AESGCMHKDFTypeURL)
62	if err != nil {
63		t.Errorf("cannot obtain AES-GCM-HKDF key manager: %s", err)
64	}
65
66	testKeys := genInvalidAESGCMHKDFKeys()
67	for i := 0; i < len(testKeys); i++ {
68		serializedKey, err := proto.Marshal(testKeys[i])
69		if err != nil {
70			t.Errorf("failed to marshal key: %s", err)
71		}
72		if _, err := keyManager.Primitive(serializedKey); err == nil {
73			t.Errorf("expect an error in test case %d", i)
74		}
75	}
76
77	if _, err := keyManager.Primitive(nil); err == nil {
78		t.Errorf("expect an error when input is nil")
79	}
80	if _, err := keyManager.Primitive([]byte{}); err == nil {
81		t.Errorf("expect an error when input is empty")
82	}
83}
84
85func TestAESGCMHKDFNewKeyMultipleTimes(t *testing.T) {
86	keyManager, err := registry.GetKeyManager(testutil.AESGCMHKDFTypeURL)
87	if err != nil {
88		t.Errorf("cannot obtain AES-GCM-HKDF key manager: %s", err)
89	}
90	format := testutil.NewAESGCMHKDFKeyFormat(32, 32, commonpb.HashType_SHA256, 4096)
91	serializedFormat, err := proto.Marshal(format)
92	if err != nil {
93		t.Errorf("failed to marshal key: %s", err)
94	}
95	keys := make(map[string]struct{})
96	n := 26
97	for i := 0; i < n; i++ {
98		key, _ := keyManager.NewKey(serializedFormat)
99		serializedKey, err := proto.Marshal(key)
100		if err != nil {
101			t.Errorf("failed to marshal key: %s", err)
102		}
103		keys[string(serializedKey)] = struct{}{}
104
105		keyData, _ := keyManager.NewKeyData(serializedFormat)
106		serializedKey = keyData.Value
107		keys[string(serializedKey)] = struct{}{}
108	}
109	if len(keys) != n*2 {
110		t.Errorf("key is repeated")
111	}
112}
113
114func TestAESGCMHKDFNewKeyBasic(t *testing.T) {
115	keyManager, err := registry.GetKeyManager(testutil.AESGCMHKDFTypeURL)
116	if err != nil {
117		t.Errorf("cannot obtain AES-GCM-HKDF key manager: %s", err)
118	}
119	for _, keySize := range aesGCMHKDFKeySizes {
120		format := testutil.NewAESGCMHKDFKeyFormat(
121			keySize,
122			keySize,
123			commonpb.HashType_SHA256,
124			4096,
125		)
126		serializedFormat, err := proto.Marshal(format)
127		if err != nil {
128			t.Errorf("failed to marshal key: %s", err)
129		}
130		m, err := keyManager.NewKey(serializedFormat)
131		if err != nil {
132			t.Errorf("unexpected error: %s", err)
133		}
134		key := m.(*gcmhkdfpb.AesGcmHkdfStreamingKey)
135		if err := validateAESGCMHKDFKey(key, format); err != nil {
136			t.Errorf("%s", err)
137		}
138	}
139}
140
141func TestAESGCMHKDFNewKeyWithInvalidInput(t *testing.T) {
142	keyManager, err := registry.GetKeyManager(testutil.AESGCMHKDFTypeURL)
143	if err != nil {
144		t.Errorf("cannot obtain AES-GCM-HKDF key manager: %s", err)
145	}
146	// bad format
147	badFormats := genInvalidAESGCMHKDFKeyFormats()
148	for i := 0; i < len(badFormats); i++ {
149		serializedFormat, err := proto.Marshal(badFormats[i])
150		if err != nil {
151			t.Errorf("failed to marshal key: %s", err)
152		}
153		if _, err := keyManager.NewKey(serializedFormat); err == nil {
154			t.Errorf("expect an error in test case %d", i)
155		}
156	}
157	// nil
158	if _, err := keyManager.NewKey(nil); err == nil {
159		t.Errorf("expect an error when input is nil")
160	}
161	// empty array
162	if _, err := keyManager.NewKey([]byte{}); err == nil {
163		t.Errorf("expect an error when input is empty")
164	}
165}
166
167func TestAESGCMHKDFNewKeyDataBasic(t *testing.T) {
168	keyManager, err := registry.GetKeyManager(testutil.AESGCMHKDFTypeURL)
169	if err != nil {
170		t.Errorf("cannot obtain AES-GCM-HKDF key manager: %s", err)
171	}
172	for _, keySize := range aesGCMHKDFKeySizes {
173		format := testutil.NewAESGCMHKDFKeyFormat(
174			keySize,
175			keySize,
176			commonpb.HashType_SHA256,
177			4096,
178		)
179		serializedFormat, err := proto.Marshal(format)
180		if err != nil {
181			t.Errorf("failed to marshal key: %s", err)
182		}
183		keyData, err := keyManager.NewKeyData(serializedFormat)
184		if err != nil {
185			t.Errorf("unexpected error: %s", err)
186		}
187		if keyData.TypeUrl != testutil.AESGCMHKDFTypeURL {
188			t.Errorf("incorrect type url")
189		}
190		if keyData.KeyMaterialType != tinkpb.KeyData_SYMMETRIC {
191			t.Errorf("incorrect key material type")
192		}
193		key := new(gcmhkdfpb.AesGcmHkdfStreamingKey)
194		if err := proto.Unmarshal(keyData.Value, key); err != nil {
195			t.Errorf("incorrect key value")
196		}
197		if err := validateAESGCMHKDFKey(key, format); err != nil {
198			t.Errorf("%s", err)
199		}
200	}
201}
202
203func TestAESGCMHKDFNewKeyDataWithInvalidInput(t *testing.T) {
204	km, err := registry.GetKeyManager(testutil.AESGCMHKDFTypeURL)
205	if err != nil {
206		t.Errorf("cannot obtain AES-GCM-HKDF key manager: %s", err)
207	}
208	badFormats := genInvalidAESGCMHKDFKeyFormats()
209	for i := 0; i < len(badFormats); i++ {
210		serializedFormat, err := proto.Marshal(badFormats[i])
211		if err != nil {
212			t.Errorf("failed to marshal key: %s", err)
213		}
214		if _, err := km.NewKeyData(serializedFormat); err == nil {
215			t.Errorf("expect an error in test case %d", i)
216		}
217	}
218	// nil input
219	if _, err := km.NewKeyData(nil); err == nil {
220		t.Errorf("expect an error when input is nil")
221	}
222	// empty input
223	if _, err := km.NewKeyData([]byte{}); err == nil {
224		t.Errorf("expect an error when input is empty")
225	}
226}
227
228func TestAESGCMHKDFDoesSupport(t *testing.T) {
229	keyManager, err := registry.GetKeyManager(testutil.AESGCMHKDFTypeURL)
230	if err != nil {
231		t.Errorf("cannot obtain AES-GCM-HKDF key manager: %s", err)
232	}
233	if !keyManager.DoesSupport(testutil.AESGCMHKDFTypeURL) {
234		t.Errorf("AESGCMHKDFKeyManager must support %s", testutil.AESGCMHKDFTypeURL)
235	}
236	if keyManager.DoesSupport("some bad type") {
237		t.Errorf("AESGCMHKDFKeyManager must support only %s", testutil.AESGCMHKDFTypeURL)
238	}
239}
240
241func TestAESGCMHKDFTypeURL(t *testing.T) {
242	keyManager, err := registry.GetKeyManager(testutil.AESGCMHKDFTypeURL)
243	if err != nil {
244		t.Errorf("cannot obtain AES-GCM-HKDF key manager: %s", err)
245	}
246	if keyManager.TypeURL() != testutil.AESGCMHKDFTypeURL {
247		t.Errorf("incorrect key type")
248	}
249}
250
251func TestAESGCMHKDFKeyMaterialType(t *testing.T) {
252	km, err := registry.GetKeyManager(testutil.AESGCMHKDFTypeURL)
253	if err != nil {
254		t.Fatalf("registry.GetKeyManager(%q) err = %v, want nil", testutil.AESGCMHKDFTypeURL, err)
255	}
256	keyManager, ok := km.(internalregistry.DerivableKeyManager)
257	if !ok {
258		t.Fatalf("key manager is not DerivableKeyManager")
259	}
260	if got, want := keyManager.KeyMaterialType(), tinkpb.KeyData_SYMMETRIC; got != want {
261		t.Errorf("KeyMaterialType() = %v, want %v", got, want)
262	}
263}
264
265func TestAESGCMHKDFDeriveKey(t *testing.T) {
266	km, err := registry.GetKeyManager(testutil.AESGCMHKDFTypeURL)
267	if err != nil {
268		t.Fatalf("registry.GetKeyManager(%q) err = %v, want nil", testutil.AESGCMHKDFTypeURL, err)
269	}
270	keyManager, ok := km.(internalregistry.DerivableKeyManager)
271	if !ok {
272		t.Fatalf("key manager is not DerivableKeyManager")
273	}
274	for _, keySize := range []uint32{16, 32} {
275		for _, derivedKeySize := range []uint32{16, 32} {
276			keyFormat := &gcmhkdfpb.AesGcmHkdfStreamingKeyFormat{
277				Version: testutil.AESGCMHKDFKeyVersion,
278				Params: &gcmhkdfpb.AesGcmHkdfStreamingParams{
279					CiphertextSegmentSize: derivedKeySize + subtle.AESGCMHKDFNoncePrefixSizeInBytes + subtle.AESGCMHKDFTagSizeInBytes + 2,
280					DerivedKeySize:        derivedKeySize,
281					HkdfHashType:          commonpb.HashType_SHA256,
282				},
283				KeySize: keySize,
284			}
285			serializedKeyFormat, err := proto.Marshal(keyFormat)
286			if err != nil {
287				t.Fatalf("proto.Marshal(%v) err = %v, want nil", keyFormat, err)
288			}
289			rand := random.GetRandomBytes(keySize)
290			buf := &bytes.Buffer{}
291			buf.Write(rand) // never returns a non-nil error
292			k, err := keyManager.DeriveKey(serializedKeyFormat, buf)
293			if err != nil {
294				t.Fatalf("keyManager.DeriveKey() err = %v, want nil", err)
295			}
296			key := k.(*gcmhkdfpb.AesGcmHkdfStreamingKey)
297			if got, want := len(key.GetKeyValue()), int(keySize); got != want {
298				t.Errorf("key length = %d, want %d", got, want)
299			}
300			if diff := cmp.Diff(key.GetKeyValue(), rand); diff != "" {
301				t.Errorf("incorrect derived key: diff = %v", diff)
302			}
303		}
304	}
305}
306
307func TestAESGCMHKDFDeriveKeyFailsWithInvalidKeyFormats(t *testing.T) {
308	km, err := registry.GetKeyManager(testutil.AESGCMHKDFTypeURL)
309	if err != nil {
310		t.Fatalf("registry.GetKeyManager(%q) err = %v, want nil", testutil.AESGCMHKDFTypeURL, err)
311	}
312	keyManager, ok := km.(internalregistry.DerivableKeyManager)
313	if !ok {
314		t.Fatalf("key manager is not DerivableKeyManager")
315	}
316
317	validKeyFormat := &gcmhkdfpb.AesGcmHkdfStreamingKeyFormat{
318		Version: testutil.AESGCMHKDFKeyVersion,
319		Params: &gcmhkdfpb.AesGcmHkdfStreamingParams{
320			CiphertextSegmentSize: 16 + subtle.AESGCMHKDFNoncePrefixSizeInBytes + subtle.AESGCMHKDFTagSizeInBytes + 2,
321			DerivedKeySize:        16,
322			HkdfHashType:          commonpb.HashType_SHA256,
323		},
324		KeySize: 16,
325	}
326	serializedValidKeyFormat, err := proto.Marshal(validKeyFormat)
327	if err != nil {
328		t.Fatalf("proto.Marshal(%v) err = %v, want nil", validKeyFormat, err)
329	}
330	buf := bytes.NewBuffer(random.GetRandomBytes(validKeyFormat.KeySize))
331	if _, err := keyManager.DeriveKey(serializedValidKeyFormat, buf); err != nil {
332		t.Fatalf("keyManager.DeriveKey() err = %v, want nil", err)
333	}
334
335	for _, test := range []struct {
336		name                  string
337		version               uint32
338		keySize               uint32
339		ciphertextSegmentSize uint32
340		derivedKeySize        uint32
341		hkdfHashType          commonpb.HashType
342	}{
343		{
344			name:                  "invalid version",
345			version:               10,
346			keySize:               validKeyFormat.KeySize,
347			ciphertextSegmentSize: validKeyFormat.Params.CiphertextSegmentSize,
348			derivedKeySize:        validKeyFormat.Params.DerivedKeySize,
349			hkdfHashType:          validKeyFormat.Params.HkdfHashType,
350		},
351		{
352			name:                  "invalid key size",
353			version:               validKeyFormat.Version,
354			keySize:               10,
355			ciphertextSegmentSize: validKeyFormat.Params.CiphertextSegmentSize,
356			derivedKeySize:        validKeyFormat.Params.DerivedKeySize,
357			hkdfHashType:          validKeyFormat.Params.HkdfHashType,
358		},
359		{
360			name:                  "invalid ciphertext segment size",
361			version:               validKeyFormat.Version,
362			keySize:               validKeyFormat.KeySize,
363			ciphertextSegmentSize: 10,
364			derivedKeySize:        validKeyFormat.Params.DerivedKeySize,
365			hkdfHashType:          validKeyFormat.Params.HkdfHashType,
366		},
367		{
368			name:                  "invalid ciphertext segment size",
369			version:               validKeyFormat.Version,
370			keySize:               validKeyFormat.KeySize,
371			ciphertextSegmentSize: 2147483648,
372			derivedKeySize:        validKeyFormat.Params.DerivedKeySize,
373			hkdfHashType:          validKeyFormat.Params.HkdfHashType,
374		},
375		{
376			name:                  "invalid derived key size",
377			version:               validKeyFormat.Version,
378			keySize:               validKeyFormat.KeySize,
379			ciphertextSegmentSize: validKeyFormat.Params.CiphertextSegmentSize,
380			derivedKeySize:        10,
381			hkdfHashType:          validKeyFormat.Params.HkdfHashType,
382		},
383		{
384			name:                  "invalid HKDF hash type",
385			version:               validKeyFormat.Version,
386			keySize:               validKeyFormat.KeySize,
387			ciphertextSegmentSize: validKeyFormat.Params.CiphertextSegmentSize,
388			derivedKeySize:        validKeyFormat.Params.DerivedKeySize,
389			hkdfHashType:          commonpb.HashType_UNKNOWN_HASH,
390		},
391		{
392			name:                  "invalid HKDF hash type",
393			version:               validKeyFormat.Version,
394			keySize:               validKeyFormat.KeySize,
395			ciphertextSegmentSize: validKeyFormat.Params.CiphertextSegmentSize,
396			derivedKeySize:        validKeyFormat.Params.DerivedKeySize,
397			hkdfHashType:          commonpb.HashType_SHA224,
398		},
399		{
400			name:                  "invalid HKDF hash type",
401			version:               validKeyFormat.Version,
402			keySize:               validKeyFormat.KeySize,
403			ciphertextSegmentSize: validKeyFormat.Params.CiphertextSegmentSize,
404			derivedKeySize:        validKeyFormat.Params.DerivedKeySize,
405			hkdfHashType:          commonpb.HashType_SHA384,
406		},
407	} {
408		t.Run(test.name, func(t *testing.T) {
409			keyFormat, err := proto.Marshal(&gcmhkdfpb.AesGcmHkdfStreamingKeyFormat{
410				Version: test.version,
411				KeySize: test.keySize,
412				Params: &gcmhkdfpb.AesGcmHkdfStreamingParams{
413					CiphertextSegmentSize: test.ciphertextSegmentSize,
414					DerivedKeySize:        test.derivedKeySize,
415					HkdfHashType:          test.hkdfHashType,
416				},
417			})
418			if err != nil {
419				t.Fatalf("proto.Marshal() err = %v, want nil", err)
420			}
421			buf := bytes.NewBuffer(random.GetRandomBytes(test.keySize))
422			if _, err := keyManager.DeriveKey(keyFormat, buf); err == nil {
423				t.Errorf("keyManager.DeriveKey() err = nil, want non-nil")
424			}
425		})
426	}
427}
428
429func TestAESGCMHKDFDeriveKeyFailsWithMalformedKeyFormats(t *testing.T) {
430	km, err := registry.GetKeyManager(testutil.AESGCMHKDFTypeURL)
431	if err != nil {
432		t.Fatalf("registry.GetKeyManager(%q) err = %v, want nil", testutil.AESGCMHKDFTypeURL, err)
433	}
434	keyManager, ok := km.(internalregistry.DerivableKeyManager)
435	if !ok {
436		t.Fatalf("key manager is not DerivableKeyManager")
437	}
438	// Proto messages start with a VarInt, which always ends with a byte with the
439	// MSB unset, so 0x80 is invalid.
440	invalidSerialization, err := hex.DecodeString("80")
441	if err != nil {
442		t.Errorf("hex.DecodeString() err = %v, want nil", err)
443	}
444	for _, test := range []struct {
445		name      string
446		keyFormat []byte
447	}{
448		{
449			name:      "nil",
450			keyFormat: nil,
451		},
452		{
453			name:      "empty",
454			keyFormat: []byte{},
455		},
456		{
457			name:      "invalid serialization",
458			keyFormat: invalidSerialization,
459		},
460	} {
461		t.Run(test.name, func(t *testing.T) {
462			buf := bytes.NewBuffer(random.GetRandomBytes(32))
463			if _, err := keyManager.DeriveKey(test.keyFormat, buf); err == nil {
464				t.Errorf("keyManager.DeriveKey() err = nil, want non-nil")
465			}
466		})
467	}
468}
469
470func TestAESGCMHKDFDeriveKeyFailsWithInsufficientRandomness(t *testing.T) {
471	km, err := registry.GetKeyManager(testutil.AESGCMHKDFTypeURL)
472	if err != nil {
473		t.Fatalf("registry.GetKeyManager(%q) err = %v, want nil", testutil.AESGCMHKDFTypeURL, err)
474	}
475	keyManager, ok := km.(internalregistry.DerivableKeyManager)
476	if !ok {
477		t.Fatalf("key manager is not DerivableKeyManager")
478	}
479	keyFormat, err := proto.Marshal(&gcmhkdfpb.AesGcmHkdfStreamingKeyFormat{
480		Version: testutil.AESGCMHKDFKeyVersion,
481		Params: &gcmhkdfpb.AesGcmHkdfStreamingParams{
482			CiphertextSegmentSize: 16 + subtle.AESGCMHKDFNoncePrefixSizeInBytes + subtle.AESGCMHKDFTagSizeInBytes + 2,
483			DerivedKeySize:        16,
484			HkdfHashType:          commonpb.HashType_SHA256,
485		},
486		KeySize: 16,
487	})
488	if err != nil {
489		t.Fatalf("proto.Marshal(%v) err = %v, want nil", keyFormat, err)
490	}
491	{
492		buf := bytes.NewBuffer(random.GetRandomBytes(16))
493		if _, err := keyManager.DeriveKey(keyFormat, buf); err != nil {
494			t.Errorf("keyManager.DeriveKey() err = %v, want nil", err)
495		}
496	}
497	{
498		insufficientBuf := bytes.NewBuffer(random.GetRandomBytes(15))
499		if _, err := keyManager.DeriveKey(keyFormat, insufficientBuf); err == nil {
500			t.Errorf("keyManager.DeriveKey() err = nil, want non-nil")
501		}
502	}
503}
504
505func genInvalidAESGCMHKDFKeys() []proto.Message {
506	return []proto.Message{
507		// not a AESGCMHKDFKey
508		testutil.NewAESGCMHKDFKeyFormat(32, 32, commonpb.HashType_SHA256, 4096),
509		// bad key size
510		testutil.NewAESGCMHKDFKey(testutil.AESGCMKeyVersion, 17, 16, commonpb.HashType_SHA256, 4096),
511		testutil.NewAESGCMHKDFKey(testutil.AESGCMKeyVersion, 16, 17, commonpb.HashType_SHA256, 4096),
512		testutil.NewAESGCMHKDFKey(testutil.AESGCMKeyVersion, 33, 33, commonpb.HashType_SHA256, 4096),
513		// bad version
514		testutil.NewAESGCMHKDFKey(testutil.AESGCMKeyVersion+1, 16, 16, commonpb.HashType_SHA256, 4096),
515	}
516}
517
518func genInvalidAESGCMHKDFKeyFormats() []proto.Message {
519	return []proto.Message{
520		// not AESGCMKeyFormat
521		testutil.NewAESGCMHKDFKey(testutil.AESGCMKeyVersion, 16, 16, commonpb.HashType_SHA256, 16),
522		// invalid key size
523		testutil.NewAESGCMHKDFKeyFormat(17, 16, commonpb.HashType_SHA256, 4096),
524		testutil.NewAESGCMHKDFKeyFormat(16, 17, commonpb.HashType_SHA256, 4096),
525		testutil.NewAESGCMHKDFKeyFormat(33, 33, commonpb.HashType_SHA256, 4096),
526	}
527}
528
529func validateAESGCMHKDFKey(key *gcmhkdfpb.AesGcmHkdfStreamingKey, format *gcmhkdfpb.AesGcmHkdfStreamingKeyFormat) error {
530	if uint32(len(key.KeyValue)) != format.KeySize {
531		return fmt.Errorf("incorrect key size")
532	}
533	if key.Version != testutil.AESGCMKeyVersion {
534		return fmt.Errorf("incorrect key version")
535	}
536	if key.Params.CiphertextSegmentSize != format.Params.CiphertextSegmentSize {
537		return fmt.Errorf("incorrect ciphertext segment size")
538	}
539	if key.Params.DerivedKeySize != format.Params.DerivedKeySize {
540		return fmt.Errorf("incorrect derived key size")
541	}
542	if key.Params.HkdfHashType != format.Params.HkdfHashType {
543		return fmt.Errorf("incorrect HKDF hash type")
544	}
545	// try to encrypt and decrypt
546	p, err := subtle.NewAESGCMHKDF(
547		key.KeyValue,
548		key.Params.HkdfHashType.String(),
549		int(key.Params.DerivedKeySize),
550		int(key.Params.CiphertextSegmentSize),
551		0,
552	)
553	if err != nil {
554		return fmt.Errorf("invalid key")
555	}
556	return validatePrimitive(p, key)
557}
558
559func validatePrimitive(p interface{}, key *gcmhkdfpb.AesGcmHkdfStreamingKey) error {
560	cipher := p.(*subtle.AESGCMHKDF)
561	if !bytes.Equal(cipher.MainKey, key.KeyValue) {
562		return fmt.Errorf("main key and primitive don't match")
563	}
564	return encryptDecrypt(cipher, cipher, 32, 32)
565}
566