xref: /aosp_15_r20/external/tink/go/aead/aead_key_templates.go (revision e7b1675dde1b92d52ec075b0a92829627f2c52a5)
1// Copyright 2018 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 aead
18
19import (
20	"fmt"
21
22	"google.golang.org/protobuf/proto"
23	"github.com/google/tink/go/internal/tinkerror"
24	ctrpb "github.com/google/tink/go/proto/aes_ctr_go_proto"
25	ctrhmacpb "github.com/google/tink/go/proto/aes_ctr_hmac_aead_go_proto"
26	gcmpb "github.com/google/tink/go/proto/aes_gcm_go_proto"
27	gcmsivpb "github.com/google/tink/go/proto/aes_gcm_siv_go_proto"
28	commonpb "github.com/google/tink/go/proto/common_go_proto"
29	hmacpb "github.com/google/tink/go/proto/hmac_go_proto"
30	kmsenvpb "github.com/google/tink/go/proto/kms_envelope_go_proto"
31	tinkpb "github.com/google/tink/go/proto/tink_go_proto"
32)
33
34// This file contains pre-generated KeyTemplates for AEAD keys. One can use these templates
35// to generate new Keysets.
36
37// AES128GCMKeyTemplate is a KeyTemplate that generates an AES-GCM key with the following parameters:
38//   - Key size: 16 bytes
39//   - Output prefix type: TINK
40func AES128GCMKeyTemplate() *tinkpb.KeyTemplate {
41	return createAESGCMKeyTemplate(16, tinkpb.OutputPrefixType_TINK)
42}
43
44// AES256GCMKeyTemplate is a KeyTemplate that generates an AES-GCM key with the following parameters:
45//   - Key size: 32 bytes
46//   - Output prefix type: TINK
47func AES256GCMKeyTemplate() *tinkpb.KeyTemplate {
48	return createAESGCMKeyTemplate(32, tinkpb.OutputPrefixType_TINK)
49}
50
51// AES256GCMNoPrefixKeyTemplate is a KeyTemplate that generates an AES-GCM key with the following parameters:
52//   - Key size: 32 bytes
53//   - Output prefix type: RAW
54func AES256GCMNoPrefixKeyTemplate() *tinkpb.KeyTemplate {
55	return createAESGCMKeyTemplate(32, tinkpb.OutputPrefixType_RAW)
56}
57
58// AES128GCMSIVKeyTemplate is a KeyTemplate that generates an AES-GCM-SIV key with the following parameters:
59//   - Key size: 16 bytes
60//   - Output prefix type: TINK
61func AES128GCMSIVKeyTemplate() *tinkpb.KeyTemplate {
62	return createAESGCMSIVKeyTemplate(16, tinkpb.OutputPrefixType_TINK)
63}
64
65// AES256GCMSIVKeyTemplate is a KeyTemplate that generates an AES-GCM-SIV key with the following parameters:
66//   - Key size: 32 bytes
67//   - Output prefix type: TINK
68func AES256GCMSIVKeyTemplate() *tinkpb.KeyTemplate {
69	return createAESGCMSIVKeyTemplate(32, tinkpb.OutputPrefixType_TINK)
70}
71
72// AES256GCMSIVNoPrefixKeyTemplate is a KeyTemplate that generates an AES-GCM key with the following parameters:
73//   - Key size: 32 bytes
74//   - Output prefix type: RAW
75func AES256GCMSIVNoPrefixKeyTemplate() *tinkpb.KeyTemplate {
76	return createAESGCMSIVKeyTemplate(32, tinkpb.OutputPrefixType_RAW)
77}
78
79// AES128CTRHMACSHA256KeyTemplate is a KeyTemplate that generates an AES-CTR-HMAC-AEAD key with the following parameters:
80//   - AES key size: 16 bytes
81//   - AES CTR IV size: 16 bytes
82//   - HMAC key size: 32 bytes
83//   - HMAC tag size: 16 bytes
84//   - HMAC hash function: SHA256
85func AES128CTRHMACSHA256KeyTemplate() *tinkpb.KeyTemplate {
86	return createAESCTRHMACAEADKeyTemplate(16, 16, 32, 16, commonpb.HashType_SHA256)
87}
88
89// AES256CTRHMACSHA256KeyTemplate is a KeyTemplate that generates an AES-CTR-HMAC-AEAD key with the following parameters:
90//   - AES key size: 32 bytes
91//   - AES CTR IV size: 16 bytes
92//   - HMAC key size: 32 bytes
93//   - HMAC tag size: 32 bytes
94//   - HMAC hash function: SHA256
95func AES256CTRHMACSHA256KeyTemplate() *tinkpb.KeyTemplate {
96	return createAESCTRHMACAEADKeyTemplate(32, 16, 32, 32, commonpb.HashType_SHA256)
97}
98
99// ChaCha20Poly1305KeyTemplate is a KeyTemplate that generates a CHACHA20_POLY1305 key.
100func ChaCha20Poly1305KeyTemplate() *tinkpb.KeyTemplate {
101	return &tinkpb.KeyTemplate{
102		// Don't set value because KeyFormat is not required.
103		TypeUrl:          chaCha20Poly1305TypeURL,
104		OutputPrefixType: tinkpb.OutputPrefixType_TINK,
105	}
106}
107
108// XChaCha20Poly1305KeyTemplate is a KeyTemplate that generates a XCHACHA20_POLY1305 key.
109func XChaCha20Poly1305KeyTemplate() *tinkpb.KeyTemplate {
110	return &tinkpb.KeyTemplate{
111		// Don't set value because KeyFormat is not required.
112		TypeUrl:          xChaCha20Poly1305TypeURL,
113		OutputPrefixType: tinkpb.OutputPrefixType_TINK,
114	}
115}
116
117// CreateKMSEnvelopeAEADKeyTemplate returns a key template that generates a
118// KMSEnvelopeAEAD key for a given key encryption key (KEK) in a remote key
119// management service (KMS).
120//
121// When performing encrypt operations, a data encryption key (DEK) is generated
122// for each ciphertext.  The DEK is wrapped by the remote KMS using the KEK and
123// stored alongside the ciphertext.
124//
125// dekTemplate must be a KeyTemplate for any of these Tink AEAD key types (any
126// other key template will be rejected):
127//   - AesCtrHmacAeadKey
128//   - AesGcmKey
129//   - ChaCha20Poly1305Key
130//   - XChaCha20Poly1305
131//   - AesGcmSivKey
132//
133// DEKs generated by this key template use the RAW output prefix to make them
134// compatible with remote KMS encrypt/decrypt operations.
135//
136// Unlike other templates, when you generate new keys with this template, Tink
137// does not generate new key material, but only creates a reference to the
138// remote KEK.
139//
140// If either uri or dekTemplate contain invalid input, an error is returned.
141func CreateKMSEnvelopeAEADKeyTemplate(uri string, dekTemplate *tinkpb.KeyTemplate) (*tinkpb.KeyTemplate, error) {
142	if !isSupporedKMSEnvelopeDEK(dekTemplate.GetTypeUrl()) {
143		return nil, fmt.Errorf("unsupported DEK key type %s. Only Tink AEAD key types are supported", dekTemplate.GetTypeUrl())
144	}
145
146	f := &kmsenvpb.KmsEnvelopeAeadKeyFormat{
147		KekUri:      uri,
148		DekTemplate: dekTemplate,
149	}
150	serializedFormat, err := proto.Marshal(f)
151	if err != nil {
152		return nil, fmt.Errorf("failed to marshal key format: %s", err)
153	}
154	return &tinkpb.KeyTemplate{
155		Value:            serializedFormat,
156		TypeUrl:          kmsEnvelopeAEADTypeURL,
157		OutputPrefixType: tinkpb.OutputPrefixType_RAW,
158	}, nil
159}
160
161// KMSEnvelopeAEADKeyTemplate returns a KeyTemplate that generates a
162// KMSEnvelopeAEAD key for a given key encryption key (KEK) in a remote key
163// management service (KMS).
164//
165// If either uri or dekTemplate contain invalid input, program execution will
166// be interrupted.
167//
168// Deprecated: Use [CreateKMSEnvelopeAEADKeyTemplate], which returns an error
169// value instead of interrupting the program.
170func KMSEnvelopeAEADKeyTemplate(uri string, dekTemplate *tinkpb.KeyTemplate) *tinkpb.KeyTemplate {
171	t, err := CreateKMSEnvelopeAEADKeyTemplate(uri, dekTemplate)
172	if err != nil {
173		tinkerror.Fail(err.Error())
174	}
175	return t
176}
177
178// createAESGCMKeyTemplate creates a new AES-GCM key template with the given key
179// size in bytes.
180func createAESGCMKeyTemplate(keySize uint32, outputPrefixType tinkpb.OutputPrefixType) *tinkpb.KeyTemplate {
181	format := &gcmpb.AesGcmKeyFormat{
182		KeySize: keySize,
183	}
184	serializedFormat, err := proto.Marshal(format)
185	if err != nil {
186		tinkerror.Fail(fmt.Sprintf("failed to marshal key format: %s", err))
187	}
188	return &tinkpb.KeyTemplate{
189		TypeUrl:          aesGCMTypeURL,
190		Value:            serializedFormat,
191		OutputPrefixType: outputPrefixType,
192	}
193}
194
195// createAESGCMSIVKeyTemplate creates a new AES-GCM-SIV key template with the given key
196// size in bytes.
197func createAESGCMSIVKeyTemplate(keySize uint32, outputPrefixType tinkpb.OutputPrefixType) *tinkpb.KeyTemplate {
198	format := &gcmsivpb.AesGcmSivKeyFormat{
199		KeySize: keySize,
200	}
201	serializedFormat, err := proto.Marshal(format)
202	if err != nil {
203		tinkerror.Fail(fmt.Sprintf("failed to marshal key format: %s", err))
204	}
205	return &tinkpb.KeyTemplate{
206		TypeUrl:          aesGCMSIVTypeURL,
207		Value:            serializedFormat,
208		OutputPrefixType: outputPrefixType,
209	}
210}
211
212func createAESCTRHMACAEADKeyTemplate(aesKeySize, ivSize, hmacKeySize, tagSize uint32, hash commonpb.HashType) *tinkpb.KeyTemplate {
213	format := &ctrhmacpb.AesCtrHmacAeadKeyFormat{
214		AesCtrKeyFormat: &ctrpb.AesCtrKeyFormat{
215			Params:  &ctrpb.AesCtrParams{IvSize: ivSize},
216			KeySize: aesKeySize,
217		},
218		HmacKeyFormat: &hmacpb.HmacKeyFormat{
219			Params:  &hmacpb.HmacParams{Hash: hash, TagSize: tagSize},
220			KeySize: hmacKeySize,
221		},
222	}
223	serializedFormat, err := proto.Marshal(format)
224	if err != nil {
225		tinkerror.Fail(fmt.Sprintf("failed to marshal key format: %s", err))
226	}
227	return &tinkpb.KeyTemplate{
228		Value:            serializedFormat,
229		TypeUrl:          aesCTRHMACAEADTypeURL,
230		OutputPrefixType: tinkpb.OutputPrefixType_TINK,
231	}
232}
233