xref: /aosp_15_r20/external/tink/go/prf/aes_cmac_prf_key_manager.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 prf
18
19import (
20	"errors"
21	"fmt"
22
23	"google.golang.org/protobuf/proto"
24	"github.com/google/tink/go/keyset"
25	"github.com/google/tink/go/prf/subtle"
26	"github.com/google/tink/go/subtle/random"
27	cmacpb "github.com/google/tink/go/proto/aes_cmac_prf_go_proto"
28	tinkpb "github.com/google/tink/go/proto/tink_go_proto"
29)
30
31const (
32	aescmacprfKeyVersion = 0
33	aescmacprfTypeURL    = "type.googleapis.com/google.crypto.tink.AesCmacPrfKey"
34)
35
36var errInvalidAESCMACPRFKey = errors.New("aes_cmac_prf_key_manager: invalid key")
37var errInvalidAESCMACPRFKeyFormat = errors.New("aes_cmac_prf_key_manager: invalid key format")
38
39// aescmacprfKeyManager generates new AES-CMAC keys and produces new instances of AES-CMAC.
40type aescmacprfKeyManager struct{}
41
42// Primitive constructs a AES-CMAC instance for the given serialized AESCMACPRFKey.
43func (km *aescmacprfKeyManager) Primitive(serializedKey []byte) (interface{}, error) {
44	if len(serializedKey) == 0 {
45		return nil, errInvalidAESCMACPRFKey
46	}
47	key := new(cmacpb.AesCmacPrfKey)
48	if err := proto.Unmarshal(serializedKey, key); err != nil {
49		return nil, errInvalidAESCMACPRFKey
50	}
51	if err := km.validateKey(key); err != nil {
52		return nil, err
53	}
54	return subtle.NewAESCMACPRF(key.KeyValue)
55}
56
57// NewKey generates a new AESCMACPRFKey according to specification in the given AESCMACPRFKeyFormat.
58func (km *aescmacprfKeyManager) NewKey(serializedKeyFormat []byte) (proto.Message, error) {
59	if len(serializedKeyFormat) == 0 {
60		return nil, errInvalidAESCMACPRFKeyFormat
61	}
62	keyFormat := new(cmacpb.AesCmacPrfKeyFormat)
63	if err := proto.Unmarshal(serializedKeyFormat, keyFormat); err != nil {
64		return nil, errInvalidAESCMACPRFKeyFormat
65	}
66	if err := km.validateKeyFormat(keyFormat); err != nil {
67		return nil, fmt.Errorf("aes_cmac_prf_key_manager: invalid key format: %s", err)
68	}
69	keyValue := random.GetRandomBytes(keyFormat.KeySize)
70	return &cmacpb.AesCmacPrfKey{
71		Version:  aescmacprfKeyVersion,
72		KeyValue: keyValue,
73	}, nil
74}
75
76// NewKeyData generates a new KeyData according to specification in the given
77// serialized AESCMACPRFKeyFormat. This should be used solely by the key management API.
78func (km *aescmacprfKeyManager) NewKeyData(serializedKeyFormat []byte) (*tinkpb.KeyData, error) {
79	key, err := km.NewKey(serializedKeyFormat)
80	if err != nil {
81		return nil, err
82	}
83	serializedKey, err := proto.Marshal(key)
84	if err != nil {
85		return nil, errInvalidAESCMACPRFKeyFormat
86	}
87
88	return &tinkpb.KeyData{
89		TypeUrl:         aescmacprfTypeURL,
90		Value:           serializedKey,
91		KeyMaterialType: tinkpb.KeyData_SYMMETRIC,
92	}, nil
93}
94
95// DoesSupport checks whether this KeyManager supports the given key type.
96func (km *aescmacprfKeyManager) DoesSupport(typeURL string) bool {
97	return typeURL == aescmacprfTypeURL
98}
99
100// TypeURL returns the type URL of keys managed by this KeyManager.
101func (km *aescmacprfKeyManager) TypeURL() string {
102	return aescmacprfTypeURL
103}
104
105// validateKey validates the given AESCMACPRFKey. It only validates the version of the
106// key because other parameters will be validated in primitive construction.
107func (km *aescmacprfKeyManager) validateKey(key *cmacpb.AesCmacPrfKey) error {
108	err := keyset.ValidateKeyVersion(key.Version, aescmacprfKeyVersion)
109	if err != nil {
110		return fmt.Errorf("aes_cmac_prf_key_manager: invalid version: %s", err)
111	}
112	keySize := uint32(len(key.KeyValue))
113	return subtle.ValidateAESCMACPRFParams(keySize)
114}
115
116// validateKeyFormat validates the given HMACKeyFormat
117func (km *aescmacprfKeyManager) validateKeyFormat(format *cmacpb.AesCmacPrfKeyFormat) error {
118	return subtle.ValidateAESCMACPRFParams(format.KeySize)
119}
120