| // Copyright 2018 Google LLC |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| // |
| //////////////////////////////////////////////////////////////////////////////// |
| |
| package aead |
| |
| import ( |
| "fmt" |
| |
| "google.golang.org/protobuf/proto" |
| "github.com/google/tink/go/internal/tinkerror" |
| ctrpb "github.com/google/tink/go/proto/aes_ctr_go_proto" |
| ctrhmacpb "github.com/google/tink/go/proto/aes_ctr_hmac_aead_go_proto" |
| gcmpb "github.com/google/tink/go/proto/aes_gcm_go_proto" |
| gcmsivpb "github.com/google/tink/go/proto/aes_gcm_siv_go_proto" |
| commonpb "github.com/google/tink/go/proto/common_go_proto" |
| hmacpb "github.com/google/tink/go/proto/hmac_go_proto" |
| kmsenvpb "github.com/google/tink/go/proto/kms_envelope_go_proto" |
| tinkpb "github.com/google/tink/go/proto/tink_go_proto" |
| ) |
| |
| // This file contains pre-generated KeyTemplates for AEAD keys. One can use these templates |
| // to generate new Keysets. |
| |
| // AES128GCMKeyTemplate is a KeyTemplate that generates an AES-GCM key with the following parameters: |
| // - Key size: 16 bytes |
| // - Output prefix type: TINK |
| func AES128GCMKeyTemplate() *tinkpb.KeyTemplate { |
| return createAESGCMKeyTemplate(16, tinkpb.OutputPrefixType_TINK) |
| } |
| |
| // AES256GCMKeyTemplate is a KeyTemplate that generates an AES-GCM key with the following parameters: |
| // - Key size: 32 bytes |
| // - Output prefix type: TINK |
| func AES256GCMKeyTemplate() *tinkpb.KeyTemplate { |
| return createAESGCMKeyTemplate(32, tinkpb.OutputPrefixType_TINK) |
| } |
| |
| // AES256GCMNoPrefixKeyTemplate is a KeyTemplate that generates an AES-GCM key with the following parameters: |
| // - Key size: 32 bytes |
| // - Output prefix type: RAW |
| func AES256GCMNoPrefixKeyTemplate() *tinkpb.KeyTemplate { |
| return createAESGCMKeyTemplate(32, tinkpb.OutputPrefixType_RAW) |
| } |
| |
| // AES128GCMSIVKeyTemplate is a KeyTemplate that generates an AES-GCM-SIV key with the following parameters: |
| // - Key size: 16 bytes |
| // - Output prefix type: TINK |
| func AES128GCMSIVKeyTemplate() *tinkpb.KeyTemplate { |
| return createAESGCMSIVKeyTemplate(16, tinkpb.OutputPrefixType_TINK) |
| } |
| |
| // AES256GCMSIVKeyTemplate is a KeyTemplate that generates an AES-GCM-SIV key with the following parameters: |
| // - Key size: 32 bytes |
| // - Output prefix type: TINK |
| func AES256GCMSIVKeyTemplate() *tinkpb.KeyTemplate { |
| return createAESGCMSIVKeyTemplate(32, tinkpb.OutputPrefixType_TINK) |
| } |
| |
| // AES256GCMSIVNoPrefixKeyTemplate is a KeyTemplate that generates an AES-GCM key with the following parameters: |
| // - Key size: 32 bytes |
| // - Output prefix type: RAW |
| func AES256GCMSIVNoPrefixKeyTemplate() *tinkpb.KeyTemplate { |
| return createAESGCMSIVKeyTemplate(32, tinkpb.OutputPrefixType_RAW) |
| } |
| |
| // AES128CTRHMACSHA256KeyTemplate is a KeyTemplate that generates an AES-CTR-HMAC-AEAD key with the following parameters: |
| // - AES key size: 16 bytes |
| // - AES CTR IV size: 16 bytes |
| // - HMAC key size: 32 bytes |
| // - HMAC tag size: 16 bytes |
| // - HMAC hash function: SHA256 |
| func AES128CTRHMACSHA256KeyTemplate() *tinkpb.KeyTemplate { |
| return createAESCTRHMACAEADKeyTemplate(16, 16, 32, 16, commonpb.HashType_SHA256) |
| } |
| |
| // AES256CTRHMACSHA256KeyTemplate is a KeyTemplate that generates an AES-CTR-HMAC-AEAD key with the following parameters: |
| // - AES key size: 32 bytes |
| // - AES CTR IV size: 16 bytes |
| // - HMAC key size: 32 bytes |
| // - HMAC tag size: 32 bytes |
| // - HMAC hash function: SHA256 |
| func AES256CTRHMACSHA256KeyTemplate() *tinkpb.KeyTemplate { |
| return createAESCTRHMACAEADKeyTemplate(32, 16, 32, 32, commonpb.HashType_SHA256) |
| } |
| |
| // ChaCha20Poly1305KeyTemplate is a KeyTemplate that generates a CHACHA20_POLY1305 key. |
| func ChaCha20Poly1305KeyTemplate() *tinkpb.KeyTemplate { |
| return &tinkpb.KeyTemplate{ |
| // Don't set value because KeyFormat is not required. |
| TypeUrl: chaCha20Poly1305TypeURL, |
| OutputPrefixType: tinkpb.OutputPrefixType_TINK, |
| } |
| } |
| |
| // XChaCha20Poly1305KeyTemplate is a KeyTemplate that generates a XCHACHA20_POLY1305 key. |
| func XChaCha20Poly1305KeyTemplate() *tinkpb.KeyTemplate { |
| return &tinkpb.KeyTemplate{ |
| // Don't set value because KeyFormat is not required. |
| TypeUrl: xChaCha20Poly1305TypeURL, |
| OutputPrefixType: tinkpb.OutputPrefixType_TINK, |
| } |
| } |
| |
| // CreateKMSEnvelopeAEADKeyTemplate returns a key template that generates a |
| // KMSEnvelopeAEAD key for a given key encryption key (KEK) in a remote key |
| // management service (KMS). |
| // |
| // When performing encrypt operations, a data encryption key (DEK) is generated |
| // for each ciphertext. The DEK is wrapped by the remote KMS using the KEK and |
| // stored alongside the ciphertext. |
| // |
| // dekTemplate must be a KeyTemplate for any of these Tink AEAD key types (any |
| // other key template will be rejected): |
| // - AesCtrHmacAeadKey |
| // - AesGcmKey |
| // - ChaCha20Poly1305Key |
| // - XChaCha20Poly1305 |
| // - AesGcmSivKey |
| // |
| // DEKs generated by this key template use the RAW output prefix to make them |
| // compatible with remote KMS encrypt/decrypt operations. |
| // |
| // Unlike other templates, when you generate new keys with this template, Tink |
| // does not generate new key material, but only creates a reference to the |
| // remote KEK. |
| // |
| // If either uri or dekTemplate contain invalid input, an error is returned. |
| func CreateKMSEnvelopeAEADKeyTemplate(uri string, dekTemplate *tinkpb.KeyTemplate) (*tinkpb.KeyTemplate, error) { |
| if !isSupporedKMSEnvelopeDEK(dekTemplate.GetTypeUrl()) { |
| return nil, fmt.Errorf("unsupported DEK key type %s. Only Tink AEAD key types are supported", dekTemplate.GetTypeUrl()) |
| } |
| |
| f := &kmsenvpb.KmsEnvelopeAeadKeyFormat{ |
| KekUri: uri, |
| DekTemplate: dekTemplate, |
| } |
| serializedFormat, err := proto.Marshal(f) |
| if err != nil { |
| return nil, fmt.Errorf("failed to marshal key format: %s", err) |
| } |
| return &tinkpb.KeyTemplate{ |
| Value: serializedFormat, |
| TypeUrl: kmsEnvelopeAEADTypeURL, |
| OutputPrefixType: tinkpb.OutputPrefixType_RAW, |
| }, nil |
| } |
| |
| // KMSEnvelopeAEADKeyTemplate returns a KeyTemplate that generates a |
| // KMSEnvelopeAEAD key for a given key encryption key (KEK) in a remote key |
| // management service (KMS). |
| // |
| // If either uri or dekTemplate contain invalid input, program execution will |
| // be interrupted. |
| // |
| // Deprecated: Use [CreateKMSEnvelopeAEADKeyTemplate], which returns an error |
| // value instead of interrupting the program. |
| func KMSEnvelopeAEADKeyTemplate(uri string, dekTemplate *tinkpb.KeyTemplate) *tinkpb.KeyTemplate { |
| t, err := CreateKMSEnvelopeAEADKeyTemplate(uri, dekTemplate) |
| if err != nil { |
| tinkerror.Fail(err.Error()) |
| } |
| return t |
| } |
| |
| // createAESGCMKeyTemplate creates a new AES-GCM key template with the given key |
| // size in bytes. |
| func createAESGCMKeyTemplate(keySize uint32, outputPrefixType tinkpb.OutputPrefixType) *tinkpb.KeyTemplate { |
| format := &gcmpb.AesGcmKeyFormat{ |
| KeySize: keySize, |
| } |
| serializedFormat, err := proto.Marshal(format) |
| if err != nil { |
| tinkerror.Fail(fmt.Sprintf("failed to marshal key format: %s", err)) |
| } |
| return &tinkpb.KeyTemplate{ |
| TypeUrl: aesGCMTypeURL, |
| Value: serializedFormat, |
| OutputPrefixType: outputPrefixType, |
| } |
| } |
| |
| // createAESGCMSIVKeyTemplate creates a new AES-GCM-SIV key template with the given key |
| // size in bytes. |
| func createAESGCMSIVKeyTemplate(keySize uint32, outputPrefixType tinkpb.OutputPrefixType) *tinkpb.KeyTemplate { |
| format := &gcmsivpb.AesGcmSivKeyFormat{ |
| KeySize: keySize, |
| } |
| serializedFormat, err := proto.Marshal(format) |
| if err != nil { |
| tinkerror.Fail(fmt.Sprintf("failed to marshal key format: %s", err)) |
| } |
| return &tinkpb.KeyTemplate{ |
| TypeUrl: aesGCMSIVTypeURL, |
| Value: serializedFormat, |
| OutputPrefixType: outputPrefixType, |
| } |
| } |
| |
| func createAESCTRHMACAEADKeyTemplate(aesKeySize, ivSize, hmacKeySize, tagSize uint32, hash commonpb.HashType) *tinkpb.KeyTemplate { |
| format := &ctrhmacpb.AesCtrHmacAeadKeyFormat{ |
| AesCtrKeyFormat: &ctrpb.AesCtrKeyFormat{ |
| Params: &ctrpb.AesCtrParams{IvSize: ivSize}, |
| KeySize: aesKeySize, |
| }, |
| HmacKeyFormat: &hmacpb.HmacKeyFormat{ |
| Params: &hmacpb.HmacParams{Hash: hash, TagSize: tagSize}, |
| KeySize: hmacKeySize, |
| }, |
| } |
| serializedFormat, err := proto.Marshal(format) |
| if err != nil { |
| tinkerror.Fail(fmt.Sprintf("failed to marshal key format: %s", err)) |
| } |
| return &tinkpb.KeyTemplate{ |
| Value: serializedFormat, |
| TypeUrl: aesCTRHMACAEADTypeURL, |
| OutputPrefixType: tinkpb.OutputPrefixType_TINK, |
| } |
| } |