• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2024 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 
17 package com.google.crypto.tink.aead;
18 
19 import com.google.crypto.tink.AccessesPartialKey;
20 import com.google.crypto.tink.Key;
21 import com.google.crypto.tink.internal.OutputPrefixUtil;
22 import com.google.crypto.tink.util.Bytes;
23 import com.google.crypto.tink.util.SecretBytes;
24 import com.google.errorprone.annotations.Immutable;
25 import com.google.errorprone.annotations.RestrictedApi;
26 import java.security.GeneralSecurityException;
27 import java.util.Objects;
28 import javax.annotation.Nullable;
29 
30 /** Represents an X-AES-GCM key used for computing AEAD. */
31 @Immutable
32 public final class XAesGcmKey extends AeadKey {
33   private final XAesGcmParameters parameters;
34   private final SecretBytes keyBytes;
35   private final Bytes outputPrefix;
36   @Nullable private final Integer idRequirement;
37 
XAesGcmKey( XAesGcmParameters parameters, SecretBytes keyBytes, Bytes outputPrefix, @Nullable Integer idRequirement)38   private XAesGcmKey(
39       XAesGcmParameters parameters,
40       SecretBytes keyBytes,
41       Bytes outputPrefix,
42       @Nullable Integer idRequirement) {
43     this.parameters = parameters;
44     this.keyBytes = keyBytes;
45     this.outputPrefix = outputPrefix;
46     this.idRequirement = idRequirement;
47   }
48 
getOutputPrefix( XAesGcmParameters parameters, @Nullable Integer idRequirement)49   private static Bytes getOutputPrefix(
50       XAesGcmParameters parameters, @Nullable Integer idRequirement) {
51     if (parameters.getVariant() == XAesGcmParameters.Variant.NO_PREFIX) {
52       return OutputPrefixUtil.EMPTY_PREFIX;
53     }
54     if (parameters.getVariant() == XAesGcmParameters.Variant.TINK) {
55       return OutputPrefixUtil.getTinkOutputPrefix(idRequirement);
56     }
57     throw new IllegalStateException("Unknown Variant: " + parameters.getVariant());
58   }
59 
60   @Override
getOutputPrefix()61   public Bytes getOutputPrefix() {
62     return outputPrefix;
63   }
64 
65   @RestrictedApi(
66       explanation = "Accessing parts of keys can produce unexpected incompatibilities, annotate the function with @AccessesPartialKey",
67       link = "https://developers.google.com/tink/design/access_control#accessing_partial_keys",
68       allowedOnPath = ".*Test\\.java",
69       allowlistAnnotations = {AccessesPartialKey.class})
create( XAesGcmParameters parameters, SecretBytes secretBytes, @Nullable Integer idRequirement)70   public static XAesGcmKey create(
71       XAesGcmParameters parameters, SecretBytes secretBytes, @Nullable Integer idRequirement)
72       throws GeneralSecurityException {
73     if (parameters.getVariant() != XAesGcmParameters.Variant.NO_PREFIX && idRequirement == null) {
74       throw new GeneralSecurityException(
75           "For given Variant "
76               + parameters.getVariant()
77               + " the value of idRequirement must be non-null");
78     }
79     if (parameters.getVariant() == XAesGcmParameters.Variant.NO_PREFIX && idRequirement != null) {
80       throw new GeneralSecurityException(
81           "For given Variant NO_PREFIX the value of idRequirement must be null");
82     }
83     if (secretBytes.size() != 32) {
84       throw new GeneralSecurityException(
85           "XAesGcmKey key must be constructed with key of length 32 bytes, not "
86               + secretBytes.size());
87     }
88     return new XAesGcmKey(
89         parameters, secretBytes, getOutputPrefix(parameters, idRequirement), idRequirement);
90   }
91 
92   @RestrictedApi(
93       explanation = "Accessing parts of keys can produce unexpected incompatibilities, annotate the function with @AccessesPartialKey",
94       link = "https://developers.google.com/tink/design/access_control#accessing_partial_keys",
95       allowedOnPath = ".*Test\\.java",
96       allowlistAnnotations = {AccessesPartialKey.class})
getKeyBytes()97   public SecretBytes getKeyBytes() {
98     return keyBytes;
99   }
100 
101   @Override
getParameters()102   public XAesGcmParameters getParameters() {
103     return parameters;
104   }
105 
106   @Override
107   @Nullable
getIdRequirementOrNull()108   public Integer getIdRequirementOrNull() {
109     return idRequirement;
110   }
111 
112   @Override
equalsKey(Key o)113   public boolean equalsKey(Key o) {
114     if (!(o instanceof XAesGcmKey)) {
115       return false;
116     }
117     XAesGcmKey that = (XAesGcmKey) o;
118     // Since outputPrefix is a function of parameters, we can ignore it here.
119     return that.parameters.equals(parameters)
120         && that.keyBytes.equalsSecretBytes(keyBytes)
121         && Objects.equals(that.idRequirement, idRequirement);
122   }
123 }
124