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