• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2023 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 AesCtrHmacAeadKeyTest {
34   @Test
buildNoPrefixVariantAndGetProperties()35   public void buildNoPrefixVariantAndGetProperties() throws Exception {
36     AesCtrHmacAeadParameters parameters =
37         AesCtrHmacAeadParameters.builder()
38             .setAesKeySizeBytes(16)
39             .setHmacKeySizeBytes(16)
40             .setTagSizeBytes(10)
41             .setIvSizeBytes(16)
42             .setHashType(AesCtrHmacAeadParameters.HashType.SHA256)
43             .setVariant(AesCtrHmacAeadParameters.Variant.NO_PREFIX)
44             .build();
45     assertThat(parameters.hasIdRequirement()).isFalse();
46     SecretBytes aesKeyBytes = SecretBytes.randomBytes(16);
47     SecretBytes hmacKeyBytes = SecretBytes.randomBytes(16);
48     AesCtrHmacAeadKey key =
49         AesCtrHmacAeadKey.builder()
50             .setParameters(parameters)
51             .setAesKeyBytes(aesKeyBytes)
52             .setHmacKeyBytes(hmacKeyBytes)
53             .build();
54     assertThat(key.getParameters()).isEqualTo(parameters);
55     assertThat(key.getAesKeyBytes()).isEqualTo(aesKeyBytes);
56     assertThat(key.getHmacKeyBytes()).isEqualTo(hmacKeyBytes);
57     assertThat(key.getOutputPrefix()).isEqualTo(Bytes.copyFrom(new byte[] {}));
58     assertThat(key.getIdRequirementOrNull()).isNull();
59   }
60 
61   @Test
buildTinkVariantAndGetProperties()62   public void buildTinkVariantAndGetProperties() throws Exception {
63     AesCtrHmacAeadParameters parameters =
64         AesCtrHmacAeadParameters.builder()
65             .setAesKeySizeBytes(16)
66             .setHmacKeySizeBytes(16)
67             .setTagSizeBytes(10)
68             .setIvSizeBytes(16)
69             .setHashType(AesCtrHmacAeadParameters.HashType.SHA256)
70             .setVariant(AesCtrHmacAeadParameters.Variant.TINK)
71             .build();
72     assertThat(parameters.hasIdRequirement()).isTrue();
73     SecretBytes aesKeyBytes = SecretBytes.randomBytes(16);
74     SecretBytes hmacKeyBytes = SecretBytes.randomBytes(16);
75     AesCtrHmacAeadKey key =
76         AesCtrHmacAeadKey.builder()
77             .setParameters(parameters)
78             .setAesKeyBytes(aesKeyBytes)
79             .setHmacKeyBytes(hmacKeyBytes)
80             .setIdRequirement(0x66AABBCC)
81             .build();
82     assertThat(key.getParameters()).isEqualTo(parameters);
83     assertThat(key.getAesKeyBytes()).isEqualTo(aesKeyBytes);
84     assertThat(key.getHmacKeyBytes()).isEqualTo(hmacKeyBytes);
85     assertThat(key.getOutputPrefix()).isEqualTo(Bytes.copyFrom(Hex.decode("0166AABBCC")));
86     assertThat(key.getIdRequirementOrNull()).isEqualTo(0x66AABBCC);
87   }
88 
89   @Test
buildCrunchyVariantAndGetProperties()90   public void buildCrunchyVariantAndGetProperties() throws Exception {
91     AesCtrHmacAeadParameters parameters =
92         AesCtrHmacAeadParameters.builder()
93             .setAesKeySizeBytes(16)
94             .setHmacKeySizeBytes(16)
95             .setTagSizeBytes(10)
96             .setIvSizeBytes(16)
97             .setHashType(AesCtrHmacAeadParameters.HashType.SHA256)
98             .setVariant(AesCtrHmacAeadParameters.Variant.CRUNCHY)
99             .build();
100     assertThat(parameters.hasIdRequirement()).isTrue();
101     SecretBytes aesKeyBytes = SecretBytes.randomBytes(16);
102     SecretBytes hmacKeyBytes = SecretBytes.randomBytes(16);
103     AesCtrHmacAeadKey key =
104         AesCtrHmacAeadKey.builder()
105             .setParameters(parameters)
106             .setAesKeyBytes(aesKeyBytes)
107             .setHmacKeyBytes(hmacKeyBytes)
108             .setIdRequirement(0x66AABBCC)
109             .build();
110     assertThat(key.getParameters()).isEqualTo(parameters);
111     assertThat(key.getAesKeyBytes()).isEqualTo(aesKeyBytes);
112     assertThat(key.getHmacKeyBytes()).isEqualTo(hmacKeyBytes);
113     assertThat(key.getOutputPrefix()).isEqualTo(Bytes.copyFrom(Hex.decode("0066AABBCC")));
114     assertThat(key.getIdRequirementOrNull()).isEqualTo(0x66AABBCC);
115   }
116 
117   @Test
emptyBuild_fails()118   public void emptyBuild_fails() throws Exception {
119     assertThrows(GeneralSecurityException.class, () -> AesCtrHmacAeadKey.builder().build());
120   }
121 
122   @Test
buildWithoutParameters_fails()123   public void buildWithoutParameters_fails() throws Exception {
124     assertThrows(
125         GeneralSecurityException.class,
126         () ->
127             AesCtrHmacAeadKey.builder()
128                 .setAesKeyBytes(SecretBytes.randomBytes(32))
129                 .setHmacKeyBytes(SecretBytes.randomBytes(32))
130                 .build());
131   }
132 
133   @Test
buildWithoutKeyBytes_fails()134   public void buildWithoutKeyBytes_fails() throws Exception {
135     AesCtrHmacAeadParameters parameters =
136         AesCtrHmacAeadParameters.builder()
137             .setAesKeySizeBytes(16)
138             .setHmacKeySizeBytes(16)
139             .setTagSizeBytes(10)
140             .setIvSizeBytes(16)
141             .setHashType(AesCtrHmacAeadParameters.HashType.SHA256)
142             .setVariant(AesCtrHmacAeadParameters.Variant.NO_PREFIX)
143             .build();
144     assertThrows(
145         GeneralSecurityException.class,
146         () -> AesCtrHmacAeadKey.builder().setParameters(parameters).build());
147   }
148 
149   @Test
paramtersRequireIdButIdIsNotSetInBuild_fails()150   public void paramtersRequireIdButIdIsNotSetInBuild_fails() throws Exception {
151     AesCtrHmacAeadParameters parametersWithIdRequirement =
152         AesCtrHmacAeadParameters.builder()
153             .setAesKeySizeBytes(16)
154             .setHmacKeySizeBytes(16)
155             .setTagSizeBytes(10)
156             .setIvSizeBytes(16)
157             .setHashType(AesCtrHmacAeadParameters.HashType.SHA256)
158             .setVariant(AesCtrHmacAeadParameters.Variant.TINK)
159             .build();
160     assertThat(parametersWithIdRequirement.hasIdRequirement()).isTrue();
161     assertThrows(
162         GeneralSecurityException.class,
163         () ->
164             AesCtrHmacAeadKey.builder()
165                 .setAesKeyBytes(SecretBytes.randomBytes(16))
166                 .setHmacKeyBytes(SecretBytes.randomBytes(16))
167                 .setParameters(parametersWithIdRequirement)
168                 .build());
169   }
170 
171   @Test
paramtersDoesNotRequireIdButIdIsSetInBuild_fails()172   public void paramtersDoesNotRequireIdButIdIsSetInBuild_fails() throws Exception {
173     AesCtrHmacAeadParameters parametersWithoutIdRequirement =
174         AesCtrHmacAeadParameters.builder()
175             .setAesKeySizeBytes(16)
176             .setHmacKeySizeBytes(16)
177             .setTagSizeBytes(10)
178             .setIvSizeBytes(16)
179             .setHashType(AesCtrHmacAeadParameters.HashType.SHA256)
180             .setVariant(AesCtrHmacAeadParameters.Variant.NO_PREFIX)
181             .build();
182     assertThat(parametersWithoutIdRequirement.hasIdRequirement()).isFalse();
183     assertThrows(
184         GeneralSecurityException.class,
185         () ->
186             AesCtrHmacAeadKey.builder()
187                 .setAesKeyBytes(SecretBytes.randomBytes(16))
188                 .setHmacKeyBytes(SecretBytes.randomBytes(16))
189                 .setParameters(parametersWithoutIdRequirement)
190                 .setIdRequirement(0x66AABBCC)
191                 .build());
192   }
193 
194   @Test
build_keyTooSmall_fails()195   public void build_keyTooSmall_fails() throws Exception {
196     AesCtrHmacAeadParameters parameters =
197         AesCtrHmacAeadParameters.builder()
198             .setAesKeySizeBytes(32)
199             .setHmacKeySizeBytes(32)
200             .setTagSizeBytes(10)
201             .setIvSizeBytes(16)
202             .setHashType(AesCtrHmacAeadParameters.HashType.SHA256)
203             .setVariant(AesCtrHmacAeadParameters.Variant.NO_PREFIX)
204             .build();
205     assertThrows(
206         GeneralSecurityException.class,
207         () ->
208             AesCtrHmacAeadKey.builder()
209                 .setParameters(parameters)
210                 .setAesKeyBytes(SecretBytes.randomBytes(16))
211                 .setHmacKeyBytes(SecretBytes.randomBytes(16))
212                 .build());
213   }
214 
215   @Test
build_keyTooLarge_fails()216   public void build_keyTooLarge_fails() throws Exception {
217     AesCtrHmacAeadParameters parameters =
218         AesCtrHmacAeadParameters.builder()
219             .setAesKeySizeBytes(16)
220             .setHmacKeySizeBytes(16)
221             .setTagSizeBytes(10)
222             .setIvSizeBytes(16)
223             .setHashType(AesCtrHmacAeadParameters.HashType.SHA256)
224             .setVariant(AesCtrHmacAeadParameters.Variant.NO_PREFIX)
225             .build();
226     assertThrows(
227         GeneralSecurityException.class,
228         () ->
229             AesCtrHmacAeadKey.builder()
230                 .setParameters(parameters)
231                 .setAesKeyBytes(SecretBytes.randomBytes(32))
232                 .setHmacKeyBytes(SecretBytes.randomBytes(32))
233                 .build());
234   }
235 
236   @Test
testEqualities()237   public void testEqualities() throws Exception {
238     SecretBytes keyBytes1 = SecretBytes.randomBytes(32);
239     SecretBytes keyBytes1Copy =
240         SecretBytes.copyFrom(
241             keyBytes1.toByteArray(InsecureSecretKeyAccess.get()), InsecureSecretKeyAccess.get());
242     SecretBytes keyBytes2 = SecretBytes.randomBytes(32);
243     SecretBytes keyBytes16 = SecretBytes.randomBytes(16);
244 
245     AesCtrHmacAeadParameters noPrefixParameters =
246         AesCtrHmacAeadParameters.builder()
247             .setAesKeySizeBytes(32)
248             .setHmacKeySizeBytes(32)
249             .setTagSizeBytes(10)
250             .setIvSizeBytes(16)
251             .setHashType(AesCtrHmacAeadParameters.HashType.SHA256)
252             .setVariant(AesCtrHmacAeadParameters.Variant.NO_PREFIX)
253             .build();
254     AesCtrHmacAeadParameters noPrefixParameters16 =
255         AesCtrHmacAeadParameters.builder()
256             .setAesKeySizeBytes(16)
257             .setHmacKeySizeBytes(16)
258             .setTagSizeBytes(10)
259             .setIvSizeBytes(16)
260             .setHashType(AesCtrHmacAeadParameters.HashType.SHA256)
261             .setVariant(AesCtrHmacAeadParameters.Variant.NO_PREFIX)
262             .build();
263     AesCtrHmacAeadParameters tinkPrefixParameters =
264         AesCtrHmacAeadParameters.builder()
265             .setAesKeySizeBytes(32)
266             .setHmacKeySizeBytes(32)
267             .setTagSizeBytes(10)
268             .setIvSizeBytes(16)
269             .setHashType(AesCtrHmacAeadParameters.HashType.SHA256)
270             .setVariant(AesCtrHmacAeadParameters.Variant.TINK)
271             .build();
272     AesCtrHmacAeadParameters crunchyPrefixParameters =
273         AesCtrHmacAeadParameters.builder()
274             .setAesKeySizeBytes(32)
275             .setHmacKeySizeBytes(32)
276             .setTagSizeBytes(10)
277             .setIvSizeBytes(16)
278             .setHashType(AesCtrHmacAeadParameters.HashType.SHA256)
279             .setVariant(AesCtrHmacAeadParameters.Variant.CRUNCHY)
280             .build();
281     AesCtrHmacAeadParameters noPrefixParametersSha512 =
282         AesCtrHmacAeadParameters.builder()
283             .setAesKeySizeBytes(32)
284             .setHmacKeySizeBytes(32)
285             .setTagSizeBytes(10)
286             .setIvSizeBytes(16)
287             .setHashType(AesCtrHmacAeadParameters.HashType.SHA512)
288             .setVariant(AesCtrHmacAeadParameters.Variant.NO_PREFIX)
289             .build();
290     AesCtrHmacAeadParameters noPrefixParametersIvSize12 =
291         AesCtrHmacAeadParameters.builder()
292             .setAesKeySizeBytes(32)
293             .setHmacKeySizeBytes(32)
294             .setTagSizeBytes(10)
295             .setIvSizeBytes(12)
296             .setHashType(AesCtrHmacAeadParameters.HashType.SHA256)
297             .setVariant(AesCtrHmacAeadParameters.Variant.NO_PREFIX)
298             .build();
299     new KeyTester()
300         .addEqualityGroup(
301             "No prefix, keyBytes1",
302             AesCtrHmacAeadKey.builder()
303                 .setParameters(noPrefixParameters)
304                 .setAesKeyBytes(keyBytes1)
305                 .setHmacKeyBytes(keyBytes1)
306                 .build(),
307             // the same key built twice must be equal
308             AesCtrHmacAeadKey.builder()
309                 .setParameters(noPrefixParameters)
310                 .setAesKeyBytes(keyBytes1)
311                 .setHmacKeyBytes(keyBytes1)
312                 .build(),
313             // the same key built with a copy of key bytes must be equal
314             AesCtrHmacAeadKey.builder()
315                 .setParameters(noPrefixParameters)
316                 .setAesKeyBytes(keyBytes1Copy)
317                 .setHmacKeyBytes(keyBytes1Copy)
318                 .build(),
319             // setting id requirement to null is equal to not setting it
320             AesCtrHmacAeadKey.builder()
321                 .setParameters(noPrefixParameters)
322                 .setAesKeyBytes(keyBytes1)
323                 .setHmacKeyBytes(keyBytes1)
324                 .setIdRequirement(null)
325                 .build())
326         // This 2 groups check that keys with different key bytes are not equal
327         .addEqualityGroup(
328             "No prefix, different aes key bytes",
329             AesCtrHmacAeadKey.builder()
330                 .setParameters(noPrefixParameters)
331                 .setAesKeyBytes(keyBytes2)
332                 .setHmacKeyBytes(keyBytes1)
333                 .build())
334         .addEqualityGroup(
335             "No prefix, different hmac key bytes",
336             AesCtrHmacAeadKey.builder()
337                 .setParameters(noPrefixParameters)
338                 .setAesKeyBytes(keyBytes1)
339                 .setHmacKeyBytes(keyBytes2)
340                 .build())
341         // This group checks that keys with different parameters are not equal
342         .addEqualityGroup(
343             "No prefix with SHA512, keyBytes1",
344             AesCtrHmacAeadKey.builder()
345                 .setParameters(noPrefixParametersSha512)
346                 .setAesKeyBytes(keyBytes1)
347                 .setHmacKeyBytes(keyBytes1)
348                 .build())
349         .addEqualityGroup(
350             "No prefix, keyBytes16",
351             AesCtrHmacAeadKey.builder()
352                 .setParameters(noPrefixParameters16)
353                 .setAesKeyBytes(keyBytes16)
354                 .setHmacKeyBytes(keyBytes16)
355                 .build())
356         .addEqualityGroup(
357             "Tink with key id 1907, keyBytes1",
358             AesCtrHmacAeadKey.builder()
359                 .setParameters(tinkPrefixParameters)
360                 .setAesKeyBytes(keyBytes1)
361                 .setHmacKeyBytes(keyBytes1)
362                 .setIdRequirement(1907)
363                 .build(),
364             AesCtrHmacAeadKey.builder()
365                 .setParameters(tinkPrefixParameters)
366                 .setAesKeyBytes(keyBytes1Copy)
367                 .setHmacKeyBytes(keyBytes1Copy)
368                 .setIdRequirement(1907)
369                 .build())
370         .addEqualityGroup(
371             "No prefix, IV size 12",
372             AesCtrHmacAeadKey.builder()
373                 .setParameters(noPrefixParametersIvSize12)
374                 .setAesKeyBytes(keyBytes1)
375                 .setHmacKeyBytes(keyBytes1)
376                 .build())
377         // This group checks that keys with different key ids are not equal
378         .addEqualityGroup(
379             "Tink with key id 1908, keyBytes1",
380             AesCtrHmacAeadKey.builder()
381                 .setParameters(tinkPrefixParameters)
382                 .setAesKeyBytes(keyBytes1)
383                 .setHmacKeyBytes(keyBytes1)
384                 .setIdRequirement(1908)
385                 .build())
386         // This group checks that keys with different output prefix types are not equal
387         .addEqualityGroup(
388             "Crunchy with key id 1907, keyBytes1",
389             AesCtrHmacAeadKey.builder()
390                 .setParameters(crunchyPrefixParameters)
391                 .setAesKeyBytes(keyBytes1)
392                 .setHmacKeyBytes(keyBytes1)
393                 .setIdRequirement(1907)
394                 .build())
395         .doTests();
396   }
397 
398   @Test
testDifferentKeyTypesEquality_fails()399   public void testDifferentKeyTypesEquality_fails() throws Exception {
400     AesGcmParameters aesGcmParameters =
401         AesGcmParameters.builder()
402             .setKeySizeBytes(16)
403             .setIvSizeBytes(16)
404             .setTagSizeBytes(16)
405             .setVariant(AesGcmParameters.Variant.NO_PREFIX)
406             .build();
407 
408     AesCtrHmacAeadParameters aesCtrHmacAeadParameters =
409         AesCtrHmacAeadParameters.builder()
410             .setAesKeySizeBytes(16)
411             .setHmacKeySizeBytes(16)
412             .setTagSizeBytes(16)
413             .setIvSizeBytes(16)
414             .setHashType(AesCtrHmacAeadParameters.HashType.SHA256)
415             .setVariant(AesCtrHmacAeadParameters.Variant.NO_PREFIX)
416             .build();
417 
418     SecretBytes keyBytes = SecretBytes.randomBytes(16);
419     AesGcmKey aesGcmKey =
420         AesGcmKey.builder().setParameters(aesGcmParameters).setKeyBytes(keyBytes).build();
421     AesCtrHmacAeadKey aesCtrHmacAeadKey =
422         AesCtrHmacAeadKey.builder()
423             .setParameters(aesCtrHmacAeadParameters)
424             .setAesKeyBytes(keyBytes)
425             .setHmacKeyBytes(keyBytes)
426             .build();
427 
428     assertThat(aesCtrHmacAeadKey.equalsKey(aesGcmKey)).isFalse();
429   }
430 }
431