• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2017 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.prf;
18 
19 import static com.google.common.truth.Truth.assertThat;
20 import static org.junit.Assert.assertThrows;
21 import static org.junit.Assert.assertTrue;
22 
23 import com.google.crypto.tink.InsecureSecretKeyAccess;
24 import com.google.crypto.tink.KeyTemplate;
25 import com.google.crypto.tink.KeyTemplates;
26 import com.google.crypto.tink.KeysetHandle;
27 import com.google.crypto.tink.Parameters;
28 import com.google.crypto.tink.RegistryConfiguration;
29 import com.google.crypto.tink.TinkProtoKeysetFormat;
30 import com.google.crypto.tink.internal.KeyManagerRegistry;
31 import com.google.crypto.tink.subtle.Hex;
32 import com.google.crypto.tink.subtle.PrfAesCmac;
33 import com.google.crypto.tink.util.SecretBytes;
34 import java.security.GeneralSecurityException;
35 import java.util.Set;
36 import java.util.TreeSet;
37 import org.junit.Before;
38 import org.junit.Test;
39 import org.junit.experimental.theories.DataPoints;
40 import org.junit.experimental.theories.FromDataPoints;
41 import org.junit.experimental.theories.Theories;
42 import org.junit.experimental.theories.Theory;
43 import org.junit.runner.RunWith;
44 
45 /** Test for AesCmacPrfKeyManager. */
46 @RunWith(Theories.class)
47 public class AesCmacPrfKeyManagerTest {
48 
49   @Before
register()50   public void register() throws Exception {
51     PrfConfig.register();
52   }
53 
54   @Test
testAes256CmacTemplate()55   public void testAes256CmacTemplate() throws Exception {
56     KeyTemplate template = AesCmacPrfKeyManager.aes256CmacTemplate();
57     assertThat(template.toParameters()).isEqualTo(AesCmacPrfParameters.create(32));
58   }
59 
60   @Test
testKeyTemplateAndManagerCompatibility()61   public void testKeyTemplateAndManagerCompatibility() throws Exception {
62     Parameters p = AesCmacPrfKeyManager.aes256CmacTemplate().toParameters();
63     assertThat(KeysetHandle.generateNew(p).getAt(0).getKey().getParameters()).isEqualTo(p);
64   }
65 
66   @DataPoints("templateNames")
67   public static final String[] KEY_TEMPLATES =
68       new String[] {
69         "AES256_CMAC_PRF", "AES_CMAC_PRF",
70       };
71 
72   @Theory
testTemplates(@romDataPoints"templateNames") String templateName)73   public void testTemplates(@FromDataPoints("templateNames") String templateName) throws Exception {
74     KeysetHandle h = KeysetHandle.generateNew(KeyTemplates.get(templateName));
75     assertThat(h.size()).isEqualTo(1);
76     assertThat(h.getAt(0).getKey().getParameters())
77         .isEqualTo(KeyTemplates.get(templateName).toParameters());
78   }
79 
80   @Test
testKeyManagerRegistered()81   public void testKeyManagerRegistered() throws Exception {
82     assertThat(
83             KeyManagerRegistry.globalInstance()
84                 .getKeyManager("type.googleapis.com/google.crypto.tink.AesCmacPrfKey", Prf.class))
85         .isNotNull();
86   }
87 
88   @Test
createKey_works()89   public void createKey_works() throws Exception {
90     AesCmacPrfParameters params = AesCmacPrfParameters.create(32);
91     KeysetHandle handle = KeysetHandle.generateNew(params);
92     assertThat(handle.size()).isEqualTo(1);
93     AesCmacPrfKey key = (AesCmacPrfKey) handle.getAt(0).getKey();
94     assertThat(key.getParameters()).isEqualTo(params);
95   }
96 
97   @Test
createKey_differentKeyValues_alwaysDifferent()98   public void createKey_differentKeyValues_alwaysDifferent() throws Exception {
99     AesCmacPrfParameters params = AesCmacPrfParameters.create(32);
100 
101     int numKeys = 100;
102     Set<String> keys = new TreeSet<>();
103     for (int i = 0; i < numKeys; i++) {
104       KeysetHandle handle = KeysetHandle.generateNew(params);
105       assertThat(handle.size()).isEqualTo(1);
106       AesCmacPrfKey key = (AesCmacPrfKey) handle.getAt(0).getKey();
107       keys.add(Hex.encode(key.getKeyBytes().toByteArray(InsecureSecretKeyAccess.get())));
108     }
109     assertThat(keys).hasSize(numKeys);
110   }
111 
112   @Test
createPrimitiveAndUseIt_works()113   public void createPrimitiveAndUseIt_works() throws Exception {
114     AesCmacPrfParameters params = AesCmacPrfParameters.create(32);
115     KeysetHandle handle = KeysetHandle.generateNew(params);
116     assertThat(handle.size()).isEqualTo(1);
117     PrfSet prfSet = handle.getPrimitive(RegistryConfiguration.get(), PrfSet.class);
118     Prf directPrf = PrfAesCmac.create((AesCmacPrfKey) handle.getAt(0).getKey());
119     assertThat(prfSet.computePrimary(new byte[0], 16))
120         .isEqualTo(directPrf.compute(new byte[0], 16));
121   }
122 
123   @Test
serializeAndDeserializeKeysets()124   public void serializeAndDeserializeKeysets() throws Exception {
125     AesCmacPrfParameters params = AesCmacPrfParameters.create(32);
126     KeysetHandle handle = KeysetHandle.generateNew(params);
127 
128     byte[] serializedKeyset =
129         TinkProtoKeysetFormat.serializeKeyset(handle, InsecureSecretKeyAccess.get());
130     KeysetHandle parsed =
131         TinkProtoKeysetFormat.parseKeyset(serializedKeyset, InsecureSecretKeyAccess.get());
132     assertTrue(parsed.equalsKeyset(handle));
133   }
134 
135   @Test
createKeyWith16Bytes_throws()136   public void createKeyWith16Bytes_throws() throws Exception {
137     AesCmacPrfParameters params = AesCmacPrfParameters.create(16);
138     assertThrows(GeneralSecurityException.class, () -> KeysetHandle.generateNew(params));
139   }
140 
141   @Test
createPrimitiveWith16Bytes_throws()142   public void createPrimitiveWith16Bytes_throws() throws Exception {
143     AesCmacPrfParameters params = AesCmacPrfParameters.create(16);
144     AesCmacPrfKey key = AesCmacPrfKey.create(params, SecretBytes.randomBytes(16));
145     KeysetHandle handle =
146         KeysetHandle.newBuilder()
147             .addEntry(KeysetHandle.importKey(key).withFixedId(1).makePrimary())
148             .build();
149     assertThrows(
150         GeneralSecurityException.class,
151         () -> handle.getPrimitive(RegistryConfiguration.get(), PrfSet.class));
152   }
153 
154   @Test
serializeDeserializeKeysetsWith16Bytes_works()155   public void serializeDeserializeKeysetsWith16Bytes_works() throws Exception {
156     AesCmacPrfParameters params = AesCmacPrfParameters.create(16);
157     AesCmacPrfKey key = AesCmacPrfKey.create(params, SecretBytes.randomBytes(16));
158     KeysetHandle handle =
159         KeysetHandle.newBuilder()
160             .addEntry(KeysetHandle.importKey(key).withFixedId(1).makePrimary())
161             .build();
162     byte[] serializedKeyset =
163         TinkProtoKeysetFormat.serializeKeyset(handle, InsecureSecretKeyAccess.get());
164     KeysetHandle parsed =
165         TinkProtoKeysetFormat.parseKeyset(serializedKeyset, InsecureSecretKeyAccess.get());
166     assertTrue(parsed.equalsKeyset(handle));
167   }
168 }
169