• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2017 Google Inc.
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.subtle;
18 
19 import static com.google.common.truth.Truth.assertThat;
20 import static org.junit.Assert.assertEquals;
21 import static org.junit.Assert.assertThrows;
22 import static org.junit.Assert.fail;
23 
24 import com.google.crypto.tink.DeterministicAead;
25 import com.google.crypto.tink.InsecureSecretKeyAccess;
26 import com.google.crypto.tink.config.TinkFips;
27 import com.google.crypto.tink.daead.AesSivKey;
28 import com.google.crypto.tink.daead.AesSivParameters;
29 import com.google.crypto.tink.mac.internal.AesUtil;
30 import com.google.crypto.tink.testing.WycheproofTestUtil;
31 import com.google.crypto.tink.util.SecretBytes;
32 import com.google.gson.JsonArray;
33 import com.google.gson.JsonObject;
34 import java.security.GeneralSecurityException;
35 import java.security.InvalidKeyException;
36 import java.util.Arrays;
37 import javax.crypto.AEADBadTagException;
38 import org.junit.Assume;
39 import org.junit.Before;
40 import org.junit.Test;
41 import org.junit.runner.RunWith;
42 import org.junit.runners.JUnit4;
43 
44 /** Tests for AesSiv */
45 @RunWith(JUnit4.class)
46 public class AesSivTest {
47 
48   private Integer[] keySizeInBytes;
49 
50   @Before
setUp()51   public void setUp() throws Exception {
52       keySizeInBytes = new Integer[] {64};
53   }
54 
55   @Test
testWycheproofVectors()56   public void testWycheproofVectors() throws Exception {
57     Assume.assumeFalse(TinkFips.useOnlyFips());
58 
59     JsonObject json =
60         WycheproofTestUtil.readJson("../wycheproof/testvectors/aes_siv_cmac_test.json");
61     JsonArray testGroups = json.getAsJsonArray("testGroups");
62     int cntSkippedTests = 0;
63     for (int i = 0; i < testGroups.size(); i++) {
64       JsonObject group = testGroups.get(i).getAsJsonObject();
65       int keySize = group.get("keySize").getAsInt();
66       JsonArray tests = group.getAsJsonArray("tests");
67       if (!Arrays.asList(keySizeInBytes).contains(keySize / 8)) {
68         cntSkippedTests += tests.size();
69         continue;
70       }
71       for (int j = 0; j < tests.size(); j++) {
72         JsonObject testcase = tests.get(j).getAsJsonObject();
73         String tcId =
74             String.format(
75                 "testcase %d (%s)",
76                 testcase.get("tcId").getAsInt(), testcase.get("comment").getAsString());
77         byte[] key = Hex.decode(testcase.get("key").getAsString());
78         byte[] msg = Hex.decode(testcase.get("msg").getAsString());
79         byte[] aad = Hex.decode(testcase.get("aad").getAsString());
80         byte[] ct = Hex.decode(testcase.get("ct").getAsString());
81         // Result is one of "valid" and "invalid".
82         // "valid" are test vectors with matching plaintext and ciphertext.
83         // "invalid" are test vectors with invalid parameters or invalid ciphertext.
84         String result = testcase.get("result").getAsString();
85         DeterministicAead daead = new AesSiv(key);
86         if (result.equals("valid")) {
87           byte[] ciphertext = daead.encryptDeterministically(msg, aad);
88           assertEquals(tcId, Hex.encode(ct), Hex.encode(ciphertext));
89           byte[] plaintext = daead.decryptDeterministically(ct, aad);
90           assertEquals(tcId, Hex.encode(msg), Hex.encode(plaintext));
91         } else {
92           assertThrows(
93               String.format("FAIL %s: decrypted invalid ciphertext", tcId),
94               GeneralSecurityException.class,
95               () -> daead.decryptDeterministically(ct, aad));
96         }
97       }
98     }
99     System.out.printf("Number of tests skipped: %d", cntSkippedTests);
100   }
101 
102   @Test
testWycheproofVectors_createNoPrefix()103   public void testWycheproofVectors_createNoPrefix() throws Exception {
104     Assume.assumeFalse(TinkFips.useOnlyFips());
105 
106     JsonObject json =
107         WycheproofTestUtil.readJson("../wycheproof/testvectors/aes_siv_cmac_test.json");
108     JsonArray testGroups = json.getAsJsonArray("testGroups");
109     int cntSkippedTests = 0;
110     for (int i = 0; i < testGroups.size(); i++) {
111       JsonObject group = testGroups.get(i).getAsJsonObject();
112       int keySize = group.get("keySize").getAsInt();
113       JsonArray tests = group.getAsJsonArray("tests");
114       if (!Arrays.asList(keySizeInBytes).contains(keySize / 8)) {
115         cntSkippedTests += tests.size();
116         continue;
117       }
118       for (int j = 0; j < tests.size(); j++) {
119         JsonObject testcase = tests.get(j).getAsJsonObject();
120         String tcId =
121             String.format(
122                 "testcase %d (%s)",
123                 testcase.get("tcId").getAsInt(), testcase.get("comment").getAsString());
124         byte[] key = Hex.decode(testcase.get("key").getAsString());
125         byte[] msg = Hex.decode(testcase.get("msg").getAsString());
126         byte[] aad = Hex.decode(testcase.get("aad").getAsString());
127         byte[] ct = Hex.decode(testcase.get("ct").getAsString());
128         // Result is one of "valid" and "invalid".
129         // "valid" are test vectors with matching plaintext and ciphertext.
130         // "invalid" are test vectors with invalid parameters or invalid ciphertext.
131         String result = testcase.get("result").getAsString();
132         AesSivParameters parameters =
133             AesSivParameters.builder()
134                 .setKeySizeBytes(64)
135                 .setVariant(AesSivParameters.Variant.NO_PREFIX)
136                 .build();
137         SecretBytes keyBytes = SecretBytes.copyFrom(key, InsecureSecretKeyAccess.get());
138         AesSivKey aesSivKey =
139             AesSivKey.builder().setParameters(parameters).setKeyBytes(keyBytes).build();
140         DeterministicAead daead = AesSiv.create(aesSivKey);
141         if (result.equals("valid")) {
142           byte[] ciphertext = daead.encryptDeterministically(msg, aad);
143           assertEquals(tcId, Hex.encode(ct), Hex.encode(ciphertext));
144           byte[] plaintext = daead.decryptDeterministically(ct, aad);
145           assertEquals(tcId, Hex.encode(msg), Hex.encode(plaintext));
146         } else {
147           assertThrows(
148               String.format("FAIL %s: decrypted invalid ciphertext", tcId),
149               GeneralSecurityException.class,
150               () -> daead.decryptDeterministically(ct, aad));
151         }
152       }
153     }
154     System.out.printf("Number of tests skipped: %d", cntSkippedTests);
155   }
156 
157   @Test
testEncryptDecryptWithEmptyPlaintext()158   public void testEncryptDecryptWithEmptyPlaintext() throws GeneralSecurityException {
159     Assume.assumeFalse(TinkFips.useOnlyFips());
160 
161     for (int keySize : keySizeInBytes) {
162       DeterministicAead dead = new AesSiv(Random.randBytes(keySize));
163       for (int triesPlaintext = 0; triesPlaintext < 100; triesPlaintext++) {
164         byte[] plaintext = new byte[0];
165         byte[] aad = Random.randBytes(Random.randInt(128) + 1);
166         byte[] ciphertext = dead.encryptDeterministically(plaintext, aad);
167         byte[] rebuiltPlaintext = dead.decryptDeterministically(ciphertext, aad);
168         assertThat(ciphertext).hasLength(AesUtil.BLOCK_SIZE);
169         assertEquals(Hex.encode(plaintext), Hex.encode(rebuiltPlaintext));
170       }
171     }
172   }
173 
174   @Test
testEncryptDecryptWithEmptyAssociatedData()175   public void testEncryptDecryptWithEmptyAssociatedData() throws GeneralSecurityException {
176     Assume.assumeFalse(TinkFips.useOnlyFips());
177 
178     for (int keySize : keySizeInBytes) {
179       DeterministicAead dead = new AesSiv(Random.randBytes(keySize));
180       for (int triesPlaintext = 0; triesPlaintext < 100; triesPlaintext++) {
181         byte[] plaintext = Random.randBytes(Random.randInt(1024) + 1);
182         byte[] aad = new byte[0];
183         byte[] rebuiltPlaintext =
184             dead.decryptDeterministically(dead.encryptDeterministically(plaintext, aad), aad);
185         assertEquals(Hex.encode(plaintext), Hex.encode(rebuiltPlaintext));
186       }
187     }
188   }
189 
190   @Test
testEncryptDecryptWithEmptyPlaintextAndEmptyAssociatedData()191   public void testEncryptDecryptWithEmptyPlaintextAndEmptyAssociatedData()
192       throws GeneralSecurityException {
193     Assume.assumeFalse(TinkFips.useOnlyFips());
194 
195     for (int keySize : keySizeInBytes) {
196       DeterministicAead dead = new AesSiv(Random.randBytes(keySize));
197       for (int triesPlaintext = 0; triesPlaintext < 100; triesPlaintext++) {
198         byte[] plaintext = new byte[0];
199         byte[] aad = new byte[0];
200         byte[] rebuiltPlaintext =
201             dead.decryptDeterministically(dead.encryptDeterministically(plaintext, aad), aad);
202         assertEquals(Hex.encode(plaintext), Hex.encode(rebuiltPlaintext));
203       }
204     }
205   }
206 
207   @Test
testEncryptDecryptWithNullAssociatedData()208   public void testEncryptDecryptWithNullAssociatedData() throws GeneralSecurityException {
209     Assume.assumeFalse(TinkFips.useOnlyFips());
210 
211     for (int keySize : keySizeInBytes) {
212       DeterministicAead dead = new AesSiv(Random.randBytes(keySize));
213       for (int triesPlaintext = 0; triesPlaintext < 100; triesPlaintext++) {
214         byte[] plaintext = Random.randBytes(Random.randInt(1024) + 1);
215         byte[] rebuiltPlaintext =
216             dead.decryptDeterministically(dead.encryptDeterministically(plaintext, null), null);
217         assertEquals(Hex.encode(plaintext), Hex.encode(rebuiltPlaintext));
218       }
219     }
220   }
221 
222   @Test
testEncryptDecryptWithNullAndEmptyAssociatedDataEquivalent()223   public void testEncryptDecryptWithNullAndEmptyAssociatedDataEquivalent()
224       throws GeneralSecurityException {
225     Assume.assumeFalse(TinkFips.useOnlyFips());
226 
227     for (int keySize : keySizeInBytes) {
228       DeterministicAead dead = new AesSiv(Random.randBytes(keySize));
229       for (int triesPlaintext = 0; triesPlaintext < 100; triesPlaintext++) {
230         byte[] plaintext = Random.randBytes(Random.randInt(1024) + 1);
231         byte[] emptyAad = new byte[0];
232         byte[] emptyAadCiphertext = dead.encryptDeterministically(plaintext, emptyAad);
233         byte[] emptyAadRebuiltPlaintext =
234                 dead.decryptDeterministically(emptyAadCiphertext, emptyAad);
235 
236         byte[] nullAadCipherText = dead.encryptDeterministically(plaintext, null);
237         byte[] nullAadRebuiltPlaintext =
238                 dead.decryptDeterministically(nullAadCipherText, null);
239 
240         assertEquals(Hex.encode(plaintext), Hex.encode(emptyAadRebuiltPlaintext));
241         assertEquals(Hex.encode(plaintext), Hex.encode(nullAadRebuiltPlaintext));
242         assertEquals(Hex.encode(emptyAadCiphertext), Hex.encode(nullAadCipherText));
243       }
244     }
245   }
246 
247   @Test
testEncryptDecryptWithEmptyPlaintextAndNullAssociatedData()248   public void testEncryptDecryptWithEmptyPlaintextAndNullAssociatedData()
249       throws GeneralSecurityException {
250     Assume.assumeFalse(TinkFips.useOnlyFips());
251 
252     for (int keySize : keySizeInBytes) {
253       DeterministicAead dead = new AesSiv(Random.randBytes(keySize));
254       for (int triesPlaintext = 0; triesPlaintext < 100; triesPlaintext++) {
255         byte[] plaintext = new byte[0];
256         byte[] rebuiltPlaintext =
257                 dead.decryptDeterministically(dead.encryptDeterministically(plaintext, null), null);
258         assertEquals(Hex.encode(plaintext), Hex.encode(rebuiltPlaintext));
259       }
260     }
261   }
262 
263   @Test
testEncryptDecrypt()264   public void testEncryptDecrypt() throws GeneralSecurityException {
265     Assume.assumeFalse(TinkFips.useOnlyFips());
266 
267     for (int keySize : keySizeInBytes) {
268       DeterministicAead dead = new AesSiv(Random.randBytes(keySize));
269 
270       for (int triesPlaintext = 0; triesPlaintext < 100; triesPlaintext++) {
271         byte[] plaintext = Random.randBytes(Random.randInt(1024) + 1);
272         byte[] aad = Random.randBytes(Random.randInt(128) + 1);
273         byte[] rebuiltPlaintext =
274             dead.decryptDeterministically(dead.encryptDeterministically(plaintext, aad), aad);
275         assertEquals(Hex.encode(plaintext), Hex.encode(rebuiltPlaintext));
276       }
277     }
278   }
279 
testModifiedCiphertext(int keySize)280   private static void testModifiedCiphertext(int keySize) throws GeneralSecurityException {
281     Assume.assumeFalse(TinkFips.useOnlyFips());
282 
283     byte[] key = Random.randBytes(keySize);
284     DeterministicAead crypter = new AesSiv(key);
285     byte[] plaintext = Random.randBytes(10);
286     byte[] aad = Random.randBytes(10);
287     byte[] ciphertext = crypter.encryptDeterministically(plaintext, aad);
288     // Flipping bits of ciphertext.
289     for (int b = 0; b < ciphertext.length; b++) {
290       for (int bit = 0; bit < 8; bit++) {
291         byte[] modified = Arrays.copyOf(ciphertext, ciphertext.length);
292         modified[b] ^= (byte) (1 << bit);
293         try {
294           byte[] unused = crypter.decryptDeterministically(modified, aad);
295           fail("Decrypting modified ciphertext should fail");
296         } catch (AEADBadTagException ex) {
297           // This is expected.
298         }
299       }
300     }
301 
302     // Truncate the message.
303     for (int length = 0; length < ciphertext.length; length++) {
304       byte[] modified = Arrays.copyOf(ciphertext, length);
305       try {
306         byte[] unused = crypter.decryptDeterministically(modified, aad);
307         fail("Decrypting modified ciphertext should fail");
308       } catch (GeneralSecurityException ex) {
309         // This is expected.
310         // This could be a AeadBadTagException when the tag verification
311         // fails or some not yet specified Exception when the ciphertext is too short.
312         // In all cases a GeneralSecurityException or a subclass of it must be thrown.
313       }
314     }
315   }
316 
317   @Test
testModifiedCiphertext()318   public void testModifiedCiphertext() throws GeneralSecurityException {
319     Assume.assumeFalse(TinkFips.useOnlyFips());
320 
321     for (int keySize : keySizeInBytes) {
322       testModifiedCiphertext(keySize);
323     }
324   }
325 
testModifiedAssociatedData(int keySize)326   private static void testModifiedAssociatedData(int keySize) throws GeneralSecurityException {
327     Assume.assumeFalse(TinkFips.useOnlyFips());
328 
329     byte[] key = Random.randBytes(keySize);
330     DeterministicAead crypter = new AesSiv(key);
331     byte[] plaintext = Random.randBytes(10);
332     byte[] aad = Random.randBytes(10);
333     byte[] ciphertext = crypter.encryptDeterministically(plaintext, aad);
334     // Flipping bits of aad.
335     for (int b = 0; b < aad.length; b++) {
336       for (int bit = 0; bit < 8; bit++) {
337         byte[] modified = Arrays.copyOf(aad, aad.length);
338         modified[b] ^= (byte) (1 << bit);
339         try {
340           byte[] unused = crypter.decryptDeterministically(ciphertext, modified);
341           fail("Decrypting modified aad should fail");
342         } catch (AEADBadTagException ex) {
343           // This is expected.
344         }
345       }
346     }
347   }
348 
349   @Test
testModifiedAssociatedData()350   public void testModifiedAssociatedData() throws GeneralSecurityException {
351     Assume.assumeFalse(TinkFips.useOnlyFips());
352 
353     for (int keySize : keySizeInBytes) {
354       testModifiedAssociatedData(keySize);
355     }
356   }
357 
358   @Test
testInvalidKeySizes()359   public void testInvalidKeySizes() throws GeneralSecurityException {
360     Assume.assumeFalse(TinkFips.useOnlyFips());
361 
362     assertThrows(InvalidKeyException.class, () -> new AesSiv(Random.randBytes(32)));
363 
364     for (int i = 0; i < 100; i++) {
365       final int j = i;
366       if (j == 48 || j == 64) {
367         continue;
368       }
369 
370       assertThrows(
371           "Keys with invalid size should not be accepted: " + j,
372           InvalidKeyException.class,
373           () -> new AesSiv(Random.randBytes(j)));
374     }
375   }
376 
377   @Test
testFailIfFipsModuleNotAvailable()378   public void testFailIfFipsModuleNotAvailable() throws Exception {
379     Assume.assumeTrue(TinkFips.useOnlyFips());
380 
381     byte[] key = Random.randBytes(16);
382     assertThrows(GeneralSecurityException.class, () -> new AesSiv(key));
383   }
384 
385   @Test
testCreate_constructor_singleTest()386   public void testCreate_constructor_singleTest() throws GeneralSecurityException {
387     Assume.assumeFalse(TinkFips.useOnlyFips());
388     byte[] key =
389         Hex.decode(
390             "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"
391                 + "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f");
392 
393     DeterministicAead daead = new AesSiv(key);
394     assertThat(daead.encryptDeterministically(Hex.decode(""), Hex.decode("FF")))
395         .isEqualTo(Hex.decode("1BC49C6A894EF5744A0A01D46608CBCC"));
396     assertThat(
397             daead.decryptDeterministically(
398                 Hex.decode("1BC49C6A894EF5744A0A01D46608CBCC"), Hex.decode("FF")))
399         .isEqualTo(Hex.decode(""));
400   }
401 
402   /** Same value as in testCreate_constructor_singleTest. */
403   @Test
testCreateForEncryptConstructorForDecrypt_noPrefix()404   public void testCreateForEncryptConstructorForDecrypt_noPrefix() throws GeneralSecurityException {
405     Assume.assumeFalse(TinkFips.useOnlyFips());
406     AesSivParameters parameters =
407         AesSivParameters.builder()
408             .setKeySizeBytes(64)
409             .setVariant(AesSivParameters.Variant.NO_PREFIX)
410             .build();
411     SecretBytes keyBytes =
412         SecretBytes.copyFrom(
413             Hex.decode(
414                 "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"
415                     + "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f"),
416             InsecureSecretKeyAccess.get());
417 
418     AesSivKey key = AesSivKey.builder().setParameters(parameters).setKeyBytes(keyBytes).build();
419     DeterministicAead daead = AesSiv.create(key);
420     assertThat(daead.encryptDeterministically(Hex.decode(""), Hex.decode("FF")))
421         .isEqualTo(Hex.decode("1BC49C6A894EF5744A0A01D46608CBCC"));
422     assertThat(
423             daead.decryptDeterministically(
424                 Hex.decode("1BC49C6A894EF5744A0A01D46608CBCC"), Hex.decode("FF")))
425         .isEqualTo(Hex.decode(""));
426   }
427 
428   @Test
testCreateForEncryptConstructorForDecrypt_tinkPrefix()429   public void testCreateForEncryptConstructorForDecrypt_tinkPrefix()
430       throws GeneralSecurityException {
431     Assume.assumeFalse(TinkFips.useOnlyFips());
432     AesSivParameters parameters =
433         AesSivParameters.builder()
434             .setKeySizeBytes(64)
435             .setVariant(AesSivParameters.Variant.TINK)
436             .build();
437     SecretBytes keyBytes =
438         SecretBytes.copyFrom(
439             Hex.decode(
440                 "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"
441                     + "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f"),
442             InsecureSecretKeyAccess.get());
443 
444     AesSivKey key =
445         AesSivKey.builder()
446             .setParameters(parameters)
447             .setKeyBytes(keyBytes)
448             .setIdRequirement(0x44556677)
449             .build();
450     DeterministicAead daead = AesSiv.create(key);
451     assertThat(daead.encryptDeterministically(Hex.decode(""), Hex.decode("FF")))
452         .isEqualTo(Hex.decode("01445566771BC49C6A894EF5744A0A01D46608CBCC"));
453     assertThat(
454             daead.decryptDeterministically(
455                 Hex.decode("01445566771BC49C6A894EF5744A0A01D46608CBCC"), Hex.decode("FF")))
456         .isEqualTo(Hex.decode(""));
457   }
458 
459   @Test
testCreateForEncryptConstructorForDecrypt_crunchyPrefix()460   public void testCreateForEncryptConstructorForDecrypt_crunchyPrefix()
461       throws GeneralSecurityException {
462     Assume.assumeFalse(TinkFips.useOnlyFips());
463     AesSivParameters parameters =
464         AesSivParameters.builder()
465             .setKeySizeBytes(64)
466             .setVariant(AesSivParameters.Variant.CRUNCHY)
467             .build();
468     SecretBytes keyBytes =
469         SecretBytes.copyFrom(
470             Hex.decode(
471                 "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"
472                     + "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f"),
473             InsecureSecretKeyAccess.get());
474 
475     AesSivKey key =
476         AesSivKey.builder()
477             .setParameters(parameters)
478             .setKeyBytes(keyBytes)
479             .setIdRequirement(0x44556677)
480             .build();
481     DeterministicAead daead = AesSiv.create(key);
482     assertThat(daead.encryptDeterministically(Hex.decode(""), Hex.decode("FF")))
483         .isEqualTo(Hex.decode("00445566771BC49C6A894EF5744A0A01D46608CBCC"));
484     assertThat(
485             daead.decryptDeterministically(
486                 Hex.decode("00445566771BC49C6A894EF5744A0A01D46608CBCC"), Hex.decode("FF")))
487         .isEqualTo(Hex.decode(""));
488   }
489 
490   @Test
testKeySize32_throws()491   public void testKeySize32_throws() throws GeneralSecurityException {
492     AesSivParameters parameters =
493         AesSivParameters.builder()
494             .setKeySizeBytes(32)
495             .setVariant(AesSivParameters.Variant.TINK)
496             .build();
497     SecretBytes keyBytes = SecretBytes.randomBytes(32);
498 
499     AesSivKey key =
500         AesSivKey.builder()
501             .setParameters(parameters)
502             .setKeyBytes(keyBytes)
503             .setIdRequirement(0x44556677)
504             .build();
505     assertThrows(GeneralSecurityException.class, () -> AesSiv.create(key));
506   }
507 
508   @Test
testKeySize48_throws()509   public void testKeySize48_throws() throws GeneralSecurityException {
510     AesSivParameters parameters =
511         AesSivParameters.builder()
512             .setKeySizeBytes(48)
513             .setVariant(AesSivParameters.Variant.NO_PREFIX)
514             .build();
515     SecretBytes keyBytes = SecretBytes.randomBytes(48);
516 
517     AesSivKey key = AesSivKey.builder().setParameters(parameters).setKeyBytes(keyBytes).build();
518     assertThrows(GeneralSecurityException.class, () -> AesSiv.create(key));
519   }
520 
521   @Test
testCreateThrowsInFipsMode()522   public void testCreateThrowsInFipsMode() throws GeneralSecurityException {
523     Assume.assumeTrue(TinkFips.useOnlyFips());
524     AesSivParameters parameters =
525         AesSivParameters.builder()
526             .setKeySizeBytes(64)
527             .setVariant(AesSivParameters.Variant.NO_PREFIX)
528             .build();
529     SecretBytes keyBytes =
530         SecretBytes.copyFrom(
531             Hex.decode(
532                 "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"
533                     + "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f"),
534             InsecureSecretKeyAccess.get());
535     AesSivKey key = AesSivKey.builder().setParameters(parameters).setKeyBytes(keyBytes).build();
536     assertThrows(GeneralSecurityException.class, () -> AesSiv.create(key));
537   }
538 }
539