1// Copyright 2022 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 hpke 18 19import ( 20 "fmt" 21 22 internalaead "github.com/google/tink/go/internal/aead" 23) 24 25// aesGCMAEAD is an AES GCM HPKE AEAD variant that implements interface 26// aead. 27type aesGCMAEAD struct { 28 // HPKE AEAD algorithm identifier. 29 aeadID uint16 30 keyLen int 31} 32 33var _ aead = (*aesGCMAEAD)(nil) 34 35// newAESGCMAEAD constructs an AES-GCM HPKE AEAD using keyLength. 36func newAESGCMAEAD(keyLength int) (*aesGCMAEAD, error) { 37 switch keyLength { 38 case 16: 39 return &aesGCMAEAD{aeadID: aes128GCM, keyLen: 16}, nil 40 case 32: 41 return &aesGCMAEAD{aeadID: aes256GCM, keyLen: 32}, nil 42 default: 43 return nil, fmt.Errorf("key length %d is not supported", keyLength) 44 } 45} 46 47func (a *aesGCMAEAD) seal(key, nonce, plaintext, associatedData []byte) ([]byte, error) { 48 if len(key) != a.keyLen { 49 return nil, fmt.Errorf("unexpected key length: got %d, want %d", len(key), a.keyLen) 50 } 51 i, err := internalaead.NewAESGCMInsecureIV(key, false /*=prependIV*/) 52 if err != nil { 53 return nil, fmt.Errorf("NewAESGCMInsecureIV: %v", err) 54 } 55 return i.Encrypt(nonce, plaintext, associatedData) 56} 57 58func (a *aesGCMAEAD) open(key, nonce, ciphertext, associatedData []byte) ([]byte, error) { 59 if len(key) != a.keyLen { 60 return nil, fmt.Errorf("unexpected key length: got %d, want %d", len(key), a.keyLen) 61 } 62 i, err := internalaead.NewAESGCMInsecureIV(key, false /*=prependIV*/) 63 if err != nil { 64 return nil, fmt.Errorf("NewAESGCMInsecureIV: %v", err) 65 } 66 return i.Decrypt(nonce, ciphertext, associatedData) 67} 68 69func (a *aesGCMAEAD) id() uint16 { 70 return a.aeadID 71} 72 73func (a *aesGCMAEAD) keyLength() int { 74 return a.keyLen 75} 76 77func (a *aesGCMAEAD) nonceLength() int { 78 return internalaead.AESGCMIVSize 79} 80