• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
17 package com.google.crypto.tink.aead;
18 
19 import static com.google.common.truth.Truth.assertThat;
20 import static org.junit.Assert.assertThrows;
21 
22 import com.google.crypto.tink.InsecureSecretKeyAccess;
23 import com.google.crypto.tink.internal.KeyTester;
24 import com.google.crypto.tink.subtle.Hex;
25 import com.google.crypto.tink.util.Bytes;
26 import com.google.crypto.tink.util.SecretBytes;
27 import java.security.GeneralSecurityException;
28 import org.junit.Test;
29 import org.junit.runner.RunWith;
30 import org.junit.runners.JUnit4;
31 
32 @RunWith(JUnit4.class)
33 public final class AesGcmKeyTest {
34 
35   @Test
buildNoPrefixVariantAndGetProperties()36   public void buildNoPrefixVariantAndGetProperties() throws Exception {
37     AesGcmParameters parameters =
38         AesGcmParameters.builder()
39             .setKeySizeBytes(16)
40             .setIvSizeBytes(16)
41             .setTagSizeBytes(16)
42             .setVariant(AesGcmParameters.Variant.NO_PREFIX)
43             .build();
44     assertThat(parameters.hasIdRequirement()).isFalse();
45     SecretBytes keyBytes = SecretBytes.randomBytes(16);
46     AesGcmKey key = AesGcmKey.builder().setParameters(parameters).setKeyBytes(keyBytes).build();
47     assertThat(key.getParameters()).isEqualTo(parameters);
48     assertThat(key.getKeyBytes()).isEqualTo(keyBytes);
49     assertThat(key.getOutputPrefix()).isEqualTo(Bytes.copyFrom(new byte[] {}));
50     assertThat(key.getIdRequirementOrNull()).isNull();
51   }
52 
53   @Test
buildTinkVariantAndGetProperties()54   public void buildTinkVariantAndGetProperties() throws Exception {
55     AesGcmParameters parameters =
56         AesGcmParameters.builder()
57             .setKeySizeBytes(24)
58             .setIvSizeBytes(16)
59             .setTagSizeBytes(16)
60             .setVariant(AesGcmParameters.Variant.TINK)
61             .build();
62     assertThat(parameters.hasIdRequirement()).isTrue();
63     SecretBytes keyBytes = SecretBytes.randomBytes(24);
64     AesGcmKey key =
65         AesGcmKey.builder()
66             .setParameters(parameters)
67             .setKeyBytes(keyBytes)
68             .setIdRequirement(0x66AABBCC)
69             .build();
70     assertThat(key.getParameters()).isEqualTo(parameters);
71     assertThat(key.getKeyBytes()).isEqualTo(keyBytes);
72     assertThat(key.getOutputPrefix()).isEqualTo(Bytes.copyFrom(Hex.decode("0166AABBCC")));
73     assertThat(key.getIdRequirementOrNull()).isEqualTo(0x66AABBCC);
74   }
75 
76   @Test
buildCrunchyVariantAndGetProperties()77   public void buildCrunchyVariantAndGetProperties() throws Exception {
78     AesGcmParameters parameters =
79         AesGcmParameters.builder()
80             .setKeySizeBytes(32)
81             .setIvSizeBytes(16)
82             .setTagSizeBytes(16)
83             .setVariant(AesGcmParameters.Variant.CRUNCHY)
84             .build();
85     assertThat(parameters.hasIdRequirement()).isTrue();
86     SecretBytes keyBytes = SecretBytes.randomBytes(32);
87     AesGcmKey key =
88         AesGcmKey.builder()
89             .setParameters(parameters)
90             .setKeyBytes(keyBytes)
91             .setIdRequirement(0x66AABBCC)
92             .build();
93     assertThat(key.getParameters()).isEqualTo(parameters);
94     assertThat(key.getKeyBytes()).isEqualTo(keyBytes);
95     assertThat(key.getOutputPrefix()).isEqualTo(Bytes.copyFrom(Hex.decode("0066AABBCC")));
96     assertThat(key.getIdRequirementOrNull()).isEqualTo(0x66AABBCC);
97   }
98 
99   @Test
emptyBuild_fails()100   public void emptyBuild_fails() throws Exception {
101     assertThrows(GeneralSecurityException.class, () -> AesGcmKey.builder().build());
102   }
103 
104   @Test
buildWithoutParameters_fails()105   public void buildWithoutParameters_fails() throws Exception {
106     assertThrows(
107         GeneralSecurityException.class,
108         () -> AesGcmKey.builder().setKeyBytes(SecretBytes.randomBytes(32)).build());
109   }
110 
111   @Test
buildWithoutKeyBytes_fails()112   public void buildWithoutKeyBytes_fails() throws Exception {
113     AesGcmParameters parameters =
114         AesGcmParameters.builder()
115             .setKeySizeBytes(16)
116             .setIvSizeBytes(16)
117             .setTagSizeBytes(16)
118             .setVariant(AesGcmParameters.Variant.NO_PREFIX)
119             .build();
120     assertThrows(
121         GeneralSecurityException.class,
122         () -> AesGcmKey.builder().setParameters(parameters).build());
123   }
124 
125   @Test
paramtersRequireIdButIdIsNotSetInBuild_fails()126   public void paramtersRequireIdButIdIsNotSetInBuild_fails() throws Exception {
127     AesGcmParameters parametersWithIdRequirement =
128         AesGcmParameters.builder()
129             .setKeySizeBytes(16)
130             .setIvSizeBytes(16)
131             .setTagSizeBytes(16)
132             .setVariant(AesGcmParameters.Variant.TINK)
133             .build();
134     assertThat(parametersWithIdRequirement.hasIdRequirement()).isTrue();
135     assertThrows(
136         GeneralSecurityException.class,
137         () ->
138             AesGcmKey.builder()
139                 .setKeyBytes(SecretBytes.randomBytes(16))
140                 .setParameters(parametersWithIdRequirement)
141                 .build());
142   }
143 
144   @Test
buildBadKeySize_fails()145   public void buildBadKeySize_fails() throws Exception {
146     AesGcmParameters parameters =
147         AesGcmParameters.builder()
148             .setKeySizeBytes(32)
149             .setIvSizeBytes(16)
150             .setTagSizeBytes(16)
151             .setVariant(AesGcmParameters.Variant.NO_PREFIX)
152             .build();
153     assertThrows(
154         GeneralSecurityException.class,
155         () ->
156             AesGcmKey.builder()
157                 .setParameters(parameters)
158                 .setKeyBytes(SecretBytes.randomBytes(16))
159                 .build());
160   }
161 
162   @Test
testEqualities()163   public void testEqualities() throws Exception {
164     SecretBytes keyBytes32 = SecretBytes.randomBytes(32);
165     SecretBytes keyBytes32Copy =
166         SecretBytes.copyFrom(
167             keyBytes32.toByteArray(InsecureSecretKeyAccess.get()), InsecureSecretKeyAccess.get());
168     SecretBytes keyBytes32Diff = SecretBytes.randomBytes(32);
169     SecretBytes keyBytes16 = SecretBytes.randomBytes(16);
170 
171     AesGcmParameters noPrefixParametersKeySize32 =
172         AesGcmParameters.builder()
173             .setKeySizeBytes(32)
174             .setIvSizeBytes(32)
175             .setTagSizeBytes(16)
176             .setVariant(AesGcmParameters.Variant.NO_PREFIX)
177             .build();
178     AesGcmParameters noPrefixParametersKeySize16 =
179         AesGcmParameters.builder()
180             .setKeySizeBytes(16)
181             .setIvSizeBytes(16)
182             .setTagSizeBytes(16)
183             .setVariant(AesGcmParameters.Variant.NO_PREFIX)
184             .build();
185     AesGcmParameters tinkPrefixParametersKeySize32 =
186         AesGcmParameters.builder()
187             .setKeySizeBytes(32)
188             .setTagSizeBytes(16)
189             .setIvSizeBytes(32)
190             .setVariant(AesGcmParameters.Variant.TINK)
191             .build();
192     AesGcmParameters crunchyPrefixParametersKeySize32 =
193         AesGcmParameters.builder()
194             .setKeySizeBytes(32)
195             .setTagSizeBytes(16)
196             .setIvSizeBytes(32)
197             .setVariant(AesGcmParameters.Variant.CRUNCHY)
198             .build();
199 
200     new KeyTester()
201         .addEqualityGroup(
202             "No prefix, keyBytes32",
203             AesGcmKey.builder()
204                 .setParameters(noPrefixParametersKeySize32)
205                 .setKeyBytes(keyBytes32)
206                 .build(),
207             // The same key built twice must be equal.
208             AesGcmKey.builder()
209                 .setParameters(noPrefixParametersKeySize32)
210                 .setKeyBytes(keyBytes32)
211                 .build(),
212             // The same key built with a copy of key bytes must be equal.
213             AesGcmKey.builder()
214                 .setParameters(noPrefixParametersKeySize32)
215                 .setKeyBytes(keyBytes32Copy)
216                 .build(),
217             // Setting id requirement to null is equal to not setting it.
218             AesGcmKey.builder()
219                 .setParameters(noPrefixParametersKeySize32)
220                 .setKeyBytes(keyBytes32)
221                 .setIdRequirement(null)
222                 .build())
223         // This group checks that keys with different key bytes are not equal.
224         .addEqualityGroup(
225             "No prefix, newly generated keyBytes32",
226             AesGcmKey.builder()
227                 .setParameters(noPrefixParametersKeySize32)
228                 .setKeyBytes(keyBytes32Diff)
229                 .build())
230         // This group checks that keys with different key sizes are not equal.
231         .addEqualityGroup(
232             "No prefix, keyBytes16",
233             AesGcmKey.builder()
234                 .setParameters(noPrefixParametersKeySize16)
235                 .setKeyBytes(keyBytes16)
236                 .build())
237         .addEqualityGroup(
238             "Tink with key id 1907, keyBytes32",
239             AesGcmKey.builder()
240                 .setParameters(tinkPrefixParametersKeySize32)
241                 .setKeyBytes(keyBytes32)
242                 .setIdRequirement(1907)
243                 .build(),
244             AesGcmKey.builder()
245                 .setParameters(tinkPrefixParametersKeySize32)
246                 .setKeyBytes(keyBytes32Copy)
247                 .setIdRequirement(1907)
248                 .build())
249         // This group checks that keys with different key ids are not equal.
250         .addEqualityGroup(
251             "Tink with key id 1908, keyBytes32",
252             AesGcmKey.builder()
253                 .setParameters(tinkPrefixParametersKeySize32)
254                 .setKeyBytes(keyBytes32)
255                 .setIdRequirement(1908)
256                 .build())
257         // This groups checks that keys with different output prefix types are not equal.
258         .addEqualityGroup(
259             "Crunchy with key id 1907, keyBytes32",
260             AesGcmKey.builder()
261                 .setParameters(crunchyPrefixParametersKeySize32)
262                 .setKeyBytes(keyBytes32)
263                 .setIdRequirement(1907)
264                 .build())
265         .doTests();
266   }
267 
268   @Test
testDifferentKeyTypesEquality_fails()269   public void testDifferentKeyTypesEquality_fails() throws Exception {
270     AesGcmParameters aesGcmParameters =
271         AesGcmParameters.builder()
272             .setKeySizeBytes(16)
273             .setIvSizeBytes(16)
274             .setTagSizeBytes(16)
275             .setVariant(AesGcmParameters.Variant.NO_PREFIX)
276             .build();
277 
278     AesEaxParameters aesEaxParameters =
279         AesEaxParameters.builder()
280             .setKeySizeBytes(16)
281             .setIvSizeBytes(16)
282             .setTagSizeBytes(16)
283             .setVariant(AesEaxParameters.Variant.NO_PREFIX)
284             .build();
285 
286     SecretBytes keyBytes = SecretBytes.randomBytes(16);
287     AesEaxKey aesEaxKey =
288         AesEaxKey.builder().setParameters(aesEaxParameters).setKeyBytes(keyBytes).build();
289     AesGcmKey aesGcmKey =
290         AesGcmKey.builder().setParameters(aesGcmParameters).setKeyBytes(keyBytes).build();
291 
292     assertThat(aesGcmKey.equalsKey(aesEaxKey)).isFalse();
293   }
294 }
295