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