• 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.aead;
18 
19 import static com.google.common.truth.Truth.assertThat;
20 import static java.nio.charset.StandardCharsets.UTF_8;
21 import static org.junit.Assert.assertTrue;
22 
23 import com.google.crypto.tink.Aead;
24 import com.google.crypto.tink.InsecureSecretKeyAccess;
25 import com.google.crypto.tink.Key;
26 import com.google.crypto.tink.KeyTemplate;
27 import com.google.crypto.tink.KeyTemplates;
28 import com.google.crypto.tink.KeysetHandle;
29 import com.google.crypto.tink.Parameters;
30 import com.google.crypto.tink.RegistryConfiguration;
31 import com.google.crypto.tink.aead.XChaCha20Poly1305Parameters.Variant;
32 import com.google.crypto.tink.internal.KeyManagerRegistry;
33 import com.google.crypto.tink.internal.SlowInputStream;
34 import com.google.crypto.tink.subtle.XChaCha20Poly1305;
35 import com.google.crypto.tink.util.SecretBytes;
36 import java.io.ByteArrayInputStream;
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 XChaCha20Poly1305KeyManager. */
46 @RunWith(Theories.class)
47 public class XChaCha20Poly1305KeyManagerTest {
48   @Before
register()49   public void register() throws Exception {
50     AeadConfig.register();
51   }
52 
53   @Test
testKeyManagerRegistered()54   public void testKeyManagerRegistered() throws Exception {
55     assertThat(
56             KeyManagerRegistry.globalInstance()
57                 .getKeyManager(
58                     "type.googleapis.com/google.crypto.tink.XChaCha20Poly1305Key", Aead.class))
59         .isNotNull();
60   }
61 
62   @Test
testXChaCha20Poly1305Template()63   public void testXChaCha20Poly1305Template() throws Exception {
64     KeyTemplate template = XChaCha20Poly1305KeyManager.xChaCha20Poly1305Template();
65     assertThat(template.toParameters())
66         .isEqualTo(XChaCha20Poly1305Parameters.create(XChaCha20Poly1305Parameters.Variant.TINK));
67   }
68 
69   @Test
testRawXChaCha20Poly1305Template()70   public void testRawXChaCha20Poly1305Template() throws Exception {
71     KeyTemplate template = XChaCha20Poly1305KeyManager.rawXChaCha20Poly1305Template();
72     assertThat(template.toParameters()).isEqualTo(XChaCha20Poly1305Parameters.create());
73   }
74 
75   @Test
testKeyTemplatesWork()76   public void testKeyTemplatesWork() throws Exception {
77     Parameters p = XChaCha20Poly1305KeyManager.xChaCha20Poly1305Template().toParameters();
78     assertThat(KeysetHandle.generateNew(p).getAt(0).getKey().getParameters()).isEqualTo(p);
79 
80     p = XChaCha20Poly1305KeyManager.rawXChaCha20Poly1305Template().toParameters();
81     assertThat(KeysetHandle.generateNew(p).getAt(0).getKey().getParameters()).isEqualTo(p);
82   }
83 
84   @DataPoints("templateNames")
85   public static final String[] KEY_TEMPLATES =
86       new String[] {"XCHACHA20_POLY1305", "XCHACHA20_POLY1305_RAW"};
87 
88   @Theory
testTemplates(@romDataPoints"templateNames") String templateName)89   public void testTemplates(@FromDataPoints("templateNames") String templateName) throws Exception {
90     KeysetHandle h = KeysetHandle.generateNew(KeyTemplates.get(templateName));
91     assertThat(h.size()).isEqualTo(1);
92     assertThat(h.getAt(0).getKey().getParameters())
93         .isEqualTo(KeyTemplates.get(templateName).toParameters());
94   }
95 
96   @Test
testCreateKeyFromRandomness_tinkVariant_works()97   public void testCreateKeyFromRandomness_tinkVariant_works() throws Exception {
98     byte[] keyMaterial =
99         new byte[] {
100           0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
101           25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35
102         };
103     XChaCha20Poly1305Parameters parameters =
104         XChaCha20Poly1305Parameters.create(XChaCha20Poly1305Parameters.Variant.TINK);
105     com.google.crypto.tink.aead.XChaCha20Poly1305Key key =
106         XChaCha20Poly1305KeyManager.createXChaChaKeyFromRandomness(
107             parameters, new ByteArrayInputStream(keyMaterial), 123, InsecureSecretKeyAccess.get());
108     byte[] truncatedKeyMaterial =
109         new byte[] {
110           0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
111           25, 26, 27, 28, 29, 30, 31
112         };
113 
114     Key expectedKey =
115         com.google.crypto.tink.aead.XChaCha20Poly1305Key.create(
116             XChaCha20Poly1305Parameters.Variant.TINK,
117             SecretBytes.copyFrom(truncatedKeyMaterial, InsecureSecretKeyAccess.get()),
118             123);
119     assertTrue(key.equalsKey(expectedKey));
120   }
121 
122   @Test
testCreateKeyFromRandomness_rawVariant_works()123   public void testCreateKeyFromRandomness_rawVariant_works() throws Exception {
124     byte[] keyMaterial =
125         new byte[] {
126           0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
127           25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35
128         };
129     XChaCha20Poly1305Parameters parameters =
130         XChaCha20Poly1305Parameters.create(XChaCha20Poly1305Parameters.Variant.NO_PREFIX);
131     com.google.crypto.tink.aead.XChaCha20Poly1305Key key =
132         XChaCha20Poly1305KeyManager.createXChaChaKeyFromRandomness(
133             parameters, new ByteArrayInputStream(keyMaterial), null, InsecureSecretKeyAccess.get());
134     byte[] truncatedKeyMaterial =
135         new byte[] {
136           0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
137           25, 26, 27, 28, 29, 30, 31
138         };
139 
140     Key expectedKey =
141         com.google.crypto.tink.aead.XChaCha20Poly1305Key.create(
142             XChaCha20Poly1305Parameters.Variant.NO_PREFIX,
143             SecretBytes.copyFrom(truncatedKeyMaterial, InsecureSecretKeyAccess.get()),
144             null);
145     assertTrue(key.equalsKey(expectedKey));
146   }
147 
148   @Test
testCreateKeyFromRandomness_slowInputStream_works()149   public void testCreateKeyFromRandomness_slowInputStream_works() throws Exception {
150     byte[] keyMaterial =
151         new byte[] {
152           0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
153           25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35
154         };
155     XChaCha20Poly1305Parameters parameters =
156         XChaCha20Poly1305Parameters.create(XChaCha20Poly1305Parameters.Variant.TINK);
157     com.google.crypto.tink.aead.XChaCha20Poly1305Key key =
158         XChaCha20Poly1305KeyManager.createXChaChaKeyFromRandomness(
159             parameters, SlowInputStream.copyFrom(keyMaterial), 1237, InsecureSecretKeyAccess.get());
160     byte[] truncatedKeyMaterial =
161         new byte[] {
162           0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
163           25, 26, 27, 28, 29, 30, 31
164         };
165 
166     Key expectedKey =
167         com.google.crypto.tink.aead.XChaCha20Poly1305Key.create(
168             XChaCha20Poly1305Parameters.Variant.TINK,
169             SecretBytes.copyFrom(truncatedKeyMaterial, InsecureSecretKeyAccess.get()),
170             1237);
171     assertTrue(key.equalsKey(expectedKey));
172   }
173 
174   @Test
callingCreateTwiceGivesDifferentKeys()175   public void callingCreateTwiceGivesDifferentKeys() throws Exception {
176     Parameters p = XChaCha20Poly1305KeyManager.xChaCha20Poly1305Template().toParameters();
177     Key key = KeysetHandle.generateNew(p).getAt(0).getKey();
178     for (int i = 0; i < 1000; ++i) {
179       assertThat(KeysetHandle.generateNew(p).getAt(0).getKey().equalsKey(key)).isFalse();
180     }
181   }
182 
183   @Test
getPrimitiveKeysetHandle()184   public void getPrimitiveKeysetHandle() throws Exception {
185     com.google.crypto.tink.aead.XChaCha20Poly1305Key key =
186         com.google.crypto.tink.aead.XChaCha20Poly1305Key.create(
187             Variant.TINK, SecretBytes.randomBytes(32), 42);
188     KeysetHandle keysetHandle =
189         KeysetHandle.newBuilder().addEntry(KeysetHandle.importKey(key).makePrimary()).build();
190     byte[] plaintext = "plaintext".getBytes(UTF_8);
191     byte[] aad = "aad".getBytes(UTF_8);
192 
193     Aead aead = keysetHandle.getPrimitive(RegistryConfiguration.get(), Aead.class);
194     Aead directAead = XChaCha20Poly1305.create(key);
195 
196 
197     assertThat(aead.decrypt(directAead.encrypt(plaintext, aad), aad)).isEqualTo(plaintext);
198     assertThat(directAead.decrypt(aead.encrypt(plaintext, aad), aad)).isEqualTo(plaintext);
199   }
200 }
201