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