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.streamingaead; 18 19 import static com.google.common.truth.Truth.assertThat; 20 21 import com.google.crypto.tink.AccessesPartialKey; 22 import com.google.crypto.tink.InsecureSecretKeyAccess; 23 import com.google.crypto.tink.KeysetHandle; 24 import com.google.crypto.tink.RegistryConfiguration; 25 import com.google.crypto.tink.StreamingAead; 26 import com.google.crypto.tink.TinkProtoKeysetFormat; 27 import com.google.crypto.tink.internal.MutableSerializationRegistry; 28 import com.google.crypto.tink.internal.ProtoKeySerialization; 29 import com.google.crypto.tink.proto.AesGcmHkdfStreamingKey; 30 import com.google.crypto.tink.proto.AesGcmHkdfStreamingParams; 31 import com.google.crypto.tink.proto.HashType; 32 import com.google.crypto.tink.proto.KeyData; 33 import com.google.crypto.tink.proto.KeyData.KeyMaterialType; 34 import com.google.crypto.tink.proto.KeyStatusType; 35 import com.google.crypto.tink.proto.Keyset; 36 import com.google.crypto.tink.proto.OutputPrefixType; 37 import com.google.crypto.tink.streamingaead.internal.LegacyAesGcmHkdfStreamingTestKeyManager; 38 import com.google.crypto.tink.subtle.Hex; 39 import com.google.crypto.tink.testing.StreamingTestUtil; 40 import com.google.crypto.tink.util.SecretBytes; 41 import com.google.protobuf.ByteString; 42 import org.junit.BeforeClass; 43 import org.junit.Test; 44 import org.junit.runner.RunWith; 45 import org.junit.runners.JUnit4; 46 47 /** Tests that ensure that StreamingAeadWrapper properly handles LegacyFullStreamingAead. */ 48 @RunWith(JUnit4.class) 49 @AccessesPartialKey 50 public class StreamingAeadWrapperLegacyTest { 51 /** Type url that LegacyFullStreamingAeadIntegration supports. */ 52 public static final String TYPE_URL = 53 "type.googleapis.com/custom.AesGcmHkdfStreamingKey"; 54 55 @BeforeClass setUp()56 public static void setUp() throws Exception { 57 StreamingAeadWrapper.register(); 58 AesCtrHmacStreamingKeyManager.register(true); 59 LegacyAesGcmHkdfStreamingTestKeyManager.register(); 60 } 61 62 @Test endToEnd_onlyLegacy_works()63 public void endToEnd_onlyLegacy_works() throws Exception { 64 AesGcmHkdfStreamingParams protoParams = 65 AesGcmHkdfStreamingParams.newBuilder() 66 .setHkdfHashType(HashType.SHA256) 67 .setDerivedKeySize(32) 68 .setCiphertextSegmentSize(64) 69 .build(); 70 AesGcmHkdfStreamingKey protoKey = 71 AesGcmHkdfStreamingKey.newBuilder() 72 .setKeyValue( 73 ByteString.copyFrom( 74 Hex.decode("abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcd"))) 75 .setParams(protoParams) 76 .build(); 77 KeyData keyData = 78 KeyData.newBuilder() 79 .setKeyMaterialType(KeyMaterialType.SYMMETRIC) 80 .setTypeUrl(TYPE_URL) 81 .setValue(protoKey.toByteString()) 82 .build(); 83 Keyset.Key rawKeysetKey = 84 Keyset.Key.newBuilder() 85 .setKeyData(keyData) 86 .setStatus(KeyStatusType.ENABLED) 87 .setKeyId(42) 88 .setOutputPrefixType(OutputPrefixType.RAW) 89 .build(); 90 KeysetHandle keysetHandle = 91 TinkProtoKeysetFormat.parseKeyset( 92 Keyset.newBuilder().addKey(rawKeysetKey).setPrimaryKeyId(42).build().toByteArray(), 93 InsecureSecretKeyAccess.get()); 94 95 StreamingAead streamingAead = 96 keysetHandle.getPrimitive(RegistryConfiguration.get(), StreamingAead.class); 97 98 // Ensure that the legacy API will be used for AesGcmHkdfStreaming. 99 assertThat( 100 MutableSerializationRegistry.globalInstance() 101 .hasParserForKey( 102 ProtoKeySerialization.create( 103 TYPE_URL, 104 rawKeysetKey.toByteString(), 105 KeyMaterialType.SYMMETRIC, 106 OutputPrefixType.RAW, 107 null))) 108 .isFalse(); 109 StreamingTestUtil.testEncryptDecrypt(streamingAead, 0, 20, 5); 110 } 111 112 @Test endToEnd_legacyAndNewApi_works()113 public void endToEnd_legacyAndNewApi_works() throws Exception { 114 AesGcmHkdfStreamingParams protoParams = 115 AesGcmHkdfStreamingParams.newBuilder() 116 .setHkdfHashType(HashType.SHA256) 117 .setDerivedKeySize(32) 118 .setCiphertextSegmentSize(64) 119 .build(); 120 AesGcmHkdfStreamingKey protoKey = 121 AesGcmHkdfStreamingKey.newBuilder() 122 .setKeyValue( 123 ByteString.copyFrom( 124 Hex.decode("abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcd"))) 125 .setParams(protoParams) 126 .build(); 127 KeyData keyData = 128 KeyData.newBuilder() 129 .setKeyMaterialType(KeyMaterialType.SYMMETRIC) 130 .setTypeUrl(TYPE_URL) 131 .setValue(protoKey.toByteString()) 132 .build(); 133 Keyset.Key rawKeysetKey = 134 Keyset.Key.newBuilder() 135 .setKeyData(keyData) 136 .setStatus(KeyStatusType.ENABLED) 137 .setKeyId(42) 138 .setOutputPrefixType(OutputPrefixType.RAW) 139 .build(); 140 KeysetHandle legacyKeysKeysetHandle = 141 TinkProtoKeysetFormat.parseKeyset( 142 Keyset.newBuilder().addKey(rawKeysetKey).setPrimaryKeyId(42).build().toByteArray(), 143 InsecureSecretKeyAccess.get()); 144 AesCtrHmacStreamingParameters programmaticParams = 145 AesCtrHmacStreamingParameters.builder() 146 .setKeySizeBytes(32) 147 .setDerivedKeySizeBytes(32) 148 .setHkdfHashType(AesCtrHmacStreamingParameters.HashType.SHA256) 149 .setHmacHashType(AesCtrHmacStreamingParameters.HashType.SHA256) 150 .setHmacTagSizeBytes(16) 151 .setCiphertextSegmentSizeBytes(64) 152 .build(); 153 AesCtrHmacStreamingKey programmaticKey = 154 AesCtrHmacStreamingKey.create( 155 programmaticParams, 156 SecretBytes.copyFrom( 157 Hex.decode("abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcd"), 158 InsecureSecretKeyAccess.get())); 159 KeysetHandle keysetHandle = 160 KeysetHandle.newBuilder(legacyKeysKeysetHandle) 161 .addEntry(KeysetHandle.importKey(programmaticKey).withFixedId(43)) 162 .build(); 163 164 StreamingAead streamingAead = 165 keysetHandle.getPrimitive(RegistryConfiguration.get(), StreamingAead.class); 166 167 // Ensure that the legacy API will be used for AesGcmHkdfStreaming. 168 assertThat( 169 MutableSerializationRegistry.globalInstance() 170 .hasParserForKey( 171 ProtoKeySerialization.create( 172 TYPE_URL, 173 rawKeysetKey.toByteString(), 174 KeyMaterialType.SYMMETRIC, 175 OutputPrefixType.RAW, 176 null))) 177 .isFalse(); 178 StreamingTestUtil.testEncryptDecrypt(streamingAead, 0, 20, 5); 179 } 180 } 181