xref: /aosp_15_r20/external/tink/go/aead/subtle/aes_gcm.go (revision e7b1675dde1b92d52ec075b0a92829627f2c52a5)
1// Copyright 2020 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 subtle
18
19import (
20	"fmt"
21
22	internalaead "github.com/google/tink/go/internal/aead"
23	"github.com/google/tink/go/subtle/random"
24	"github.com/google/tink/go/tink"
25)
26
27const (
28	// AESGCMIVSize is the acceptable IV size defined by RFC 5116.
29	AESGCMIVSize = 12
30	// AESGCMTagSize is the acceptable tag size defined by RFC 5116.
31	AESGCMTagSize = 16
32)
33
34// AESGCM is an implementation of AEAD interface.
35type AESGCM struct {
36	aesGCMInsecureIV *internalaead.AESGCMInsecureIV
37}
38
39// Assert that AESGCM implements the AEAD interface.
40var _ tink.AEAD = (*AESGCM)(nil)
41
42// NewAESGCM returns an AESGCM instance, where key is the AES key with length
43// 16 bytes (AES-128) or 32 bytes (AES-256).
44func NewAESGCM(key []byte) (*AESGCM, error) {
45	aesGCMInsecureIV, err := internalaead.NewAESGCMInsecureIV(key, true /*=prependIV*/)
46	return &AESGCM{aesGCMInsecureIV}, err
47}
48
49// Encrypt encrypts plaintext with associatedData. The returned ciphertext
50// contains both the IV used for encryption and the actual ciphertext.
51//
52// Note: The crypto library's AES-GCM implementation always returns the
53// ciphertext with an AESGCMTagSize (16-byte) tag.
54func (a *AESGCM) Encrypt(plaintext, associatedData []byte) ([]byte, error) {
55	iv := random.GetRandomBytes(AESGCMIVSize)
56	return a.aesGCMInsecureIV.Encrypt(iv, plaintext, associatedData)
57}
58
59// Decrypt decrypts ciphertext with associatedData.
60func (a *AESGCM) Decrypt(ciphertext, associatedData []byte) ([]byte, error) {
61	if len(ciphertext) < AESGCMIVSize {
62		return nil, fmt.Errorf("ciphertext with size %d is too short", len(ciphertext))
63	}
64	iv := ciphertext[:AESGCMIVSize]
65	return a.aesGCMInsecureIV.Decrypt(iv, ciphertext, associatedData)
66}
67
68// Key returns the AES key.
69func (a *AESGCM) Key() []byte {
70	return a.aesGCMInsecureIV.Key
71}
72