xref: /aosp_15_r20/external/tink/go/daead/aes_siv_key_manager.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 daead
18
19import (
20	"errors"
21	"fmt"
22	"io"
23
24	"google.golang.org/protobuf/proto"
25	"github.com/google/tink/go/core/registry"
26	"github.com/google/tink/go/daead/subtle"
27	"github.com/google/tink/go/keyset"
28	"github.com/google/tink/go/subtle/random"
29
30	aspb "github.com/google/tink/go/proto/aes_siv_go_proto"
31	tpb "github.com/google/tink/go/proto/tink_go_proto"
32)
33
34const (
35	aesSIVKeyVersion = 0
36	aesSIVTypeURL    = "type.googleapis.com/google.crypto.tink.AesSivKey"
37)
38
39var (
40	errInvalidAESSIVKeyFormat = errors.New("aes_siv_key_manager: invalid key format")
41	errInvalidAESSIVKeySize   = fmt.Errorf("aes_siv_key_manager: key size != %d", subtle.AESSIVKeySize)
42)
43
44// aesSIVKeyManager generates AES-SIV keys and produces instances of AES-SIV.
45type aesSIVKeyManager struct{}
46
47// Assert that aesSIVKeyManager implements the KeyManager interface.
48var _ registry.KeyManager = (*aesSIVKeyManager)(nil)
49
50// Primitive constructs an AES-SIV for the given serialized AesSivKey.
51func (km *aesSIVKeyManager) Primitive(serializedKey []byte) (interface{}, error) {
52	if len(serializedKey) == 0 {
53		return nil, errors.New("aes_siv_key_manager: invalid key")
54	}
55	key := new(aspb.AesSivKey)
56	if err := proto.Unmarshal(serializedKey, key); err != nil {
57		return nil, err
58	}
59	if err := km.validateKey(key); err != nil {
60		return nil, err
61	}
62	ret, err := subtle.NewAESSIV(key.KeyValue)
63	if err != nil {
64		return nil, fmt.Errorf("aes_siv_key_manager: cannot create new primitive: %v", err)
65	}
66	return ret, nil
67}
68
69// NewKey generates a new AesSivKey. serializedKeyFormat is optional because
70// there is only one valid key format.
71func (km *aesSIVKeyManager) NewKey(serializedKeyFormat []byte) (proto.Message, error) {
72	// A nil serializedKeyFormat is acceptable. If specified, validate.
73	if serializedKeyFormat != nil {
74		keyFormat := new(aspb.AesSivKeyFormat)
75		if err := proto.Unmarshal(serializedKeyFormat, keyFormat); err != nil {
76			return nil, errInvalidAESSIVKeyFormat
77		}
78		if keyFormat.KeySize != subtle.AESSIVKeySize {
79			return nil, errInvalidAESSIVKeySize
80		}
81	}
82	return &aspb.AesSivKey{
83		Version:  aesSIVKeyVersion,
84		KeyValue: random.GetRandomBytes(subtle.AESSIVKeySize),
85	}, nil
86}
87
88// NewKeyData generates a new KeyData. serializedKeyFormat is optional because
89// there is only one valid key format. This should be used solely by the key
90// management API.
91func (km *aesSIVKeyManager) NewKeyData(serializedKeyFormat []byte) (*tpb.KeyData, error) {
92	key, err := km.NewKey(serializedKeyFormat)
93	if err != nil {
94		return nil, err
95	}
96	serializedKey, err := proto.Marshal(key)
97	if err != nil {
98		return nil, fmt.Errorf("aes_siv_key_manager: %v", err)
99	}
100	return &tpb.KeyData{
101		TypeUrl:         aesSIVTypeURL,
102		Value:           serializedKey,
103		KeyMaterialType: km.KeyMaterialType(),
104	}, nil
105}
106
107// DoesSupport checks whether this key manager supports the given key type.
108func (km *aesSIVKeyManager) DoesSupport(typeURL string) bool {
109	return typeURL == aesSIVTypeURL
110}
111
112// TypeURL returns the type URL of keys managed by this key manager.
113func (km *aesSIVKeyManager) TypeURL() string {
114	return aesSIVTypeURL
115}
116
117// KeyMaterialType returns the key material type of this key manager.
118func (km *aesSIVKeyManager) KeyMaterialType() tpb.KeyData_KeyMaterialType {
119	return tpb.KeyData_SYMMETRIC
120}
121
122// DeriveKey derives a new key from serializedKeyFormat and pseudorandomness.
123// Unlike NewKey, DeriveKey validates serializedKeyFormat.
124func (km *aesSIVKeyManager) DeriveKey(serializedKeyFormat []byte, pseudorandomness io.Reader) (proto.Message, error) {
125	keyFormat := new(aspb.AesSivKeyFormat)
126	if err := proto.Unmarshal(serializedKeyFormat, keyFormat); err != nil {
127		return nil, errInvalidAESSIVKeyFormat
128	}
129	if keyFormat.GetKeySize() != subtle.AESSIVKeySize {
130		return nil, errInvalidAESSIVKeySize
131	}
132	if err := keyset.ValidateKeyVersion(keyFormat.GetVersion(), aesSIVKeyVersion); err != nil {
133		return nil, fmt.Errorf("aes_siv_key_manager: invalid key version: %s", err)
134	}
135
136	keyValue := make([]byte, subtle.AESSIVKeySize)
137	if _, err := io.ReadFull(pseudorandomness, keyValue); err != nil {
138		return nil, fmt.Errorf("aes_siv_key_manager: not enough pseudorandomness given")
139	}
140	return &aspb.AesSivKey{
141		Version:  aesSIVKeyVersion,
142		KeyValue: keyValue,
143	}, nil
144}
145
146// validateKey validates the given AesSivKey.
147func (km *aesSIVKeyManager) validateKey(key *aspb.AesSivKey) error {
148	err := keyset.ValidateKeyVersion(key.Version, aesSIVKeyVersion)
149	if err != nil {
150		return fmt.Errorf("aes_siv_key_manager: %v", err)
151	}
152	keySize := uint32(len(key.KeyValue))
153	if keySize != subtle.AESSIVKeySize {
154		return errInvalidAESSIVKeySize
155	}
156	return nil
157}
158