2424import com .google .crypto .tink .KeyTemplate ;
2525import com .google .crypto .tink .KeyTemplates ;
2626import com .google .crypto .tink .KeysetHandle ;
27+ import com .google .crypto .tink .KmsClient ;
28+ import com .google .crypto .tink .KmsClients ;
2729import com .google .crypto .tink .internal .KeyTemplateProtoConverter ;
2830import com .google .crypto .tink .mac .HmacKeyManager ;
31+ import com .google .crypto .tink .subtle .Random ;
32+ import com .google .crypto .tink .testing .FakeKmsClient ;
2933import java .security .GeneralSecurityException ;
3034import org .junit .BeforeClass ;
3135import org .junit .Test ;
@@ -50,6 +54,33 @@ private Aead generateNewRemoteAead() throws GeneralSecurityException {
5054 return keysetHandle .getPrimitive (Aead .class );
5155 }
5256
57+ @ DataPoints ("dekParameters" )
58+ public static final AeadParameters [] DEK_PARAMETERS =
59+ new AeadParameters [] {
60+ PredefinedAeadParameters .AES128_GCM ,
61+ PredefinedAeadParameters .AES256_GCM ,
62+ PredefinedAeadParameters .AES128_EAX ,
63+ PredefinedAeadParameters .AES256_EAX ,
64+ PredefinedAeadParameters .AES128_CTR_HMAC_SHA256 ,
65+ PredefinedAeadParameters .AES256_CTR_HMAC_SHA256 ,
66+ PredefinedAeadParameters .CHACHA20_POLY1305 ,
67+ PredefinedAeadParameters .XCHACHA20_POLY1305 ,
68+ };
69+
70+ @ Theory
71+ public void createEncryptDecrypt_works (
72+ @ FromDataPoints ("dekParameters" ) AeadParameters dekParameters ) throws Exception {
73+ Aead remoteAead = this .generateNewRemoteAead ();
74+ Aead envAead = KmsEnvelopeAead .create (dekParameters , remoteAead );
75+ byte [] plaintext = "plaintext" .getBytes (UTF_8 );
76+ byte [] associatedData = "associatedData" .getBytes (UTF_8 );
77+ byte [] ciphertext = envAead .encrypt (plaintext , associatedData );
78+ assertThat (envAead .decrypt (ciphertext , associatedData )).isEqualTo (plaintext );
79+
80+ assertThat (envAead .decrypt (envAead .encrypt (plaintext , EMPTY_ADD ), EMPTY_ADD ))
81+ .isEqualTo (plaintext );
82+ }
83+
5384 @ DataPoints ("tinkDekTemplates" )
5485 public static final String [] TINK_DEK_TEMPLATES =
5586 new String [] {
@@ -65,10 +96,10 @@ private Aead generateNewRemoteAead() throws GeneralSecurityException {
6596 };
6697
6798 @ Theory
68- public void encryptDecrypt_works ( @ FromDataPoints ( "tinkDekTemplates" ) String dekTemplateName )
69- throws Exception {
99+ public void legacyConstructorEncryptDecrypt_works (
100+ @ FromDataPoints ( "tinkDekTemplates" ) String dekTemplateName ) throws Exception {
70101 Aead remoteAead = this .generateNewRemoteAead ();
71- KmsEnvelopeAead envAead =
102+ Aead envAead =
72103 new KmsEnvelopeAead (
73104 KeyTemplateProtoConverter .toProto (KeyTemplates .get (dekTemplateName )), remoteAead );
74105 byte [] plaintext = "plaintext" .getBytes (UTF_8 );
@@ -94,9 +125,7 @@ public void createKeyFormatWithInvalidDekTemplate_fails() throws Exception {
94125 @ Test
95126 public void decryptWithInvalidAssociatedData_fails () throws GeneralSecurityException {
96127 Aead remoteAead = this .generateNewRemoteAead ();
97- KmsEnvelopeAead envAead =
98- new KmsEnvelopeAead (
99- KeyTemplateProtoConverter .toProto (KeyTemplates .get ("AES128_EAX" )), remoteAead );
128+ Aead envAead = KmsEnvelopeAead .create (PredefinedAeadParameters .AES128_EAX , remoteAead );
100129 byte [] plaintext = "plaintext" .getBytes (UTF_8 );
101130 byte [] associatedData = "associatedData" .getBytes (UTF_8 );
102131 byte [] ciphertext = envAead .encrypt (plaintext , associatedData );
@@ -109,9 +138,7 @@ public void decryptWithInvalidAssociatedData_fails() throws GeneralSecurityExcep
109138 @ Test
110139 public void corruptedCiphertext_fails () throws GeneralSecurityException {
111140 Aead remoteAead = this .generateNewRemoteAead ();
112- KmsEnvelopeAead envAead =
113- new KmsEnvelopeAead (
114- KeyTemplateProtoConverter .toProto (KeyTemplates .get ("AES128_EAX" )), remoteAead );
141+ Aead envAead = KmsEnvelopeAead .create (PredefinedAeadParameters .AES128_EAX , remoteAead );
115142 byte [] associatedData = "envelope_ad" .getBytes (UTF_8 );
116143 byte [] plaintext = "helloworld" .getBytes (UTF_8 );
117144 byte [] ciphertext = envAead .encrypt (plaintext , associatedData );
@@ -124,9 +151,7 @@ public void corruptedCiphertext_fails() throws GeneralSecurityException {
124151 @ Test
125152 public void corruptedDek_fails () throws GeneralSecurityException {
126153 Aead remoteAead = this .generateNewRemoteAead ();
127- KmsEnvelopeAead envAead =
128- new KmsEnvelopeAead (
129- KeyTemplateProtoConverter .toProto (KeyTemplates .get ("AES128_EAX" )), remoteAead );
154+ Aead envAead = KmsEnvelopeAead .create (PredefinedAeadParameters .AES128_EAX , remoteAead );
130155 byte [] plaintext = "helloworld" .getBytes (UTF_8 );
131156 byte [] associatedData = "envelope_ad" .getBytes (UTF_8 );
132157 byte [] ciphertext = envAead .encrypt (plaintext , associatedData );
@@ -139,9 +164,7 @@ public void corruptedDek_fails() throws GeneralSecurityException {
139164 @ Test
140165 public void ciphertextTooShort_fails () throws GeneralSecurityException {
141166 Aead remoteAead = this .generateNewRemoteAead ();
142- KmsEnvelopeAead envAead =
143- new KmsEnvelopeAead (
144- KeyTemplateProtoConverter .toProto (KeyTemplates .get ("AES128_EAX" )), remoteAead );
167+ Aead envAead = KmsEnvelopeAead .create (PredefinedAeadParameters .AES128_EAX , remoteAead );
145168 assertThrows (
146169 GeneralSecurityException .class ,
147170 () -> envAead .decrypt ("foo" .getBytes (UTF_8 ), "envelope_ad" .getBytes (UTF_8 )));
@@ -150,9 +173,7 @@ public void ciphertextTooShort_fails() throws GeneralSecurityException {
150173 @ Test
151174 public void malformedDekLength_fails () throws GeneralSecurityException {
152175 Aead remoteAead = this .generateNewRemoteAead ();
153- KmsEnvelopeAead envAead =
154- new KmsEnvelopeAead (
155- KeyTemplateProtoConverter .toProto (KeyTemplates .get ("AES128_EAX" )), remoteAead );
176+ Aead envAead = KmsEnvelopeAead .create (PredefinedAeadParameters .AES128_EAX , remoteAead );
156177
157178 byte [] plaintext = "helloworld" .getBytes (UTF_8 );
158179 byte [] associatedData = "envelope_ad" .getBytes (UTF_8 );
@@ -174,6 +195,53 @@ public void malformedDekLength_fails() throws GeneralSecurityException {
174195 GeneralSecurityException .class ,
175196 () -> envAead .decrypt (corruptedCiphertext2 , associatedData ));
176197 }
198+
199+ @ Test
200+ public void create_isCompatibleWithOldConstructor () throws Exception {
201+ String kekUri = FakeKmsClient .createFakeKeyUri ();
202+ Aead remoteAead = new FakeKmsClient ().getAead (kekUri );
203+
204+ Aead aead1 =
205+ new KmsEnvelopeAead (
206+ KeyTemplateProtoConverter .toProto (
207+ AesCtrHmacAeadKeyManager .aes128CtrHmacSha256Template ()),
208+ remoteAead );
209+ Aead aead2 =
210+ KmsEnvelopeAead .create (PredefinedAeadParameters .AES128_CTR_HMAC_SHA256 , remoteAead );
211+
212+ byte [] plaintext = Random .randBytes (20 );
213+ byte [] associatedData = Random .randBytes (20 );
214+ assertThat (aead1 .decrypt (aead2 .encrypt (plaintext , associatedData ), associatedData ))
215+ .isEqualTo (plaintext );
216+ assertThat (aead2 .decrypt (aead1 .encrypt (plaintext , associatedData ), associatedData ))
217+ .isEqualTo (plaintext );
218+ }
219+
220+ @ Test
221+ public void create_isCompatibleWithKmsEnvelopeAeadKey () throws Exception {
222+ String kekUri = FakeKmsClient .createFakeKeyUri ();
223+ KeyTemplate dekTemplate = AesCtrHmacAeadKeyManager .aes128CtrHmacSha256Template ();
224+
225+ // Register kmsClient and create a keyset with a KmsEnvelopeAeadKey key.
226+ KmsClient kmsClient1 = new FakeKmsClient (kekUri );
227+ KmsClients .add (kmsClient1 );
228+ KeysetHandle handle1 =
229+ KeysetHandle .generateNew (KmsEnvelopeAeadKeyManager .createKeyTemplate (kekUri , dekTemplate ));
230+ Aead aead1 = handle1 .getPrimitive (Aead .class );
231+
232+ // Get Aead object from the kmsClient, and create the envelope AEAD without the registry.
233+ Aead remoteAead = new FakeKmsClient ().getAead (kekUri );
234+ Aead aead2 =
235+ KmsEnvelopeAead .create (PredefinedAeadParameters .AES128_CTR_HMAC_SHA256 , remoteAead );
236+
237+ // Check that aead1 and aead2 implement the same primitive
238+ byte [] plaintext = Random .randBytes (20 );
239+ byte [] associatedData = Random .randBytes (20 );
240+ assertThat (aead1 .decrypt (aead2 .encrypt (plaintext , associatedData ), associatedData ))
241+ .isEqualTo (plaintext );
242+ assertThat (aead2 .decrypt (aead1 .encrypt (plaintext , associatedData ), associatedData ))
243+ .isEqualTo (plaintext );
244+ }
177245}
178246
179247
0 commit comments