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 import static org.junit.Assert.assertThrows; 21 22 import com.google.crypto.tink.aead.XChaCha20Poly1305Parameters; 23 import java.security.GeneralSecurityException; 24 import org.junit.Test; 25 import org.junit.runner.RunWith; 26 import org.junit.runners.JUnit4; 27 28 @RunWith(JUnit4.class) 29 public final class AesGcmHkdfStreamingParametersTest { 30 @Test buildParametersAndGetProperties()31 public void buildParametersAndGetProperties() throws Exception { 32 AesGcmHkdfStreamingParameters parameters = 33 AesGcmHkdfStreamingParameters.builder() 34 .setKeySizeBytes(19) 35 .setDerivedAesGcmKeySizeBytes(16) 36 .setHkdfHashType(AesGcmHkdfStreamingParameters.HashType.SHA256) 37 .setCiphertextSegmentSizeBytes(1024 * 1024) 38 .build(); 39 assertThat(parameters.getKeySizeBytes()).isEqualTo(19); 40 assertThat(parameters.getDerivedAesGcmKeySizeBytes()).isEqualTo(16); 41 assertThat(parameters.getCiphertextSegmentSizeBytes()).isEqualTo(1024 * 1024); 42 assertThat(parameters.getHkdfHashType()) 43 .isEqualTo(AesGcmHkdfStreamingParameters.HashType.SHA256); 44 assertThat(parameters.hasIdRequirement()).isFalse(); 45 } 46 47 @Test buildParametersVariedValues()48 public void buildParametersVariedValues() throws Exception { 49 AesGcmHkdfStreamingParameters parameters = 50 AesGcmHkdfStreamingParameters.builder() 51 .setKeySizeBytes(77) 52 .setDerivedAesGcmKeySizeBytes(32) 53 .setHkdfHashType(AesGcmHkdfStreamingParameters.HashType.SHA1) 54 .setCiphertextSegmentSizeBytes(3 * 1024 * 1024) 55 .build(); 56 assertThat(parameters.getKeySizeBytes()).isEqualTo(77); 57 assertThat(parameters.getDerivedAesGcmKeySizeBytes()).isEqualTo(32); 58 assertThat(parameters.getCiphertextSegmentSizeBytes()).isEqualTo(3 * 1024 * 1024); 59 assertThat(parameters.getHkdfHashType()).isEqualTo(AesGcmHkdfStreamingParameters.HashType.SHA1); 60 assertThat(parameters.hasIdRequirement()).isFalse(); 61 } 62 63 @Test buildParametersWithoutSettingKeySize_fails()64 public void buildParametersWithoutSettingKeySize_fails() throws Exception { 65 AesGcmHkdfStreamingParameters.Builder builder = 66 AesGcmHkdfStreamingParameters.builder() 67 .setDerivedAesGcmKeySizeBytes(16) 68 .setHkdfHashType(AesGcmHkdfStreamingParameters.HashType.SHA256) 69 .setCiphertextSegmentSizeBytes(1024 * 1024); 70 assertThrows(GeneralSecurityException.class, builder::build); 71 } 72 73 @Test buildParametersWithoutSettingDerivedKeySize_fails()74 public void buildParametersWithoutSettingDerivedKeySize_fails() throws Exception { 75 AesGcmHkdfStreamingParameters.Builder builder = 76 AesGcmHkdfStreamingParameters.builder() 77 .setKeySizeBytes(19) 78 .setHkdfHashType(AesGcmHkdfStreamingParameters.HashType.SHA256) 79 .setCiphertextSegmentSizeBytes(1024 * 1024); 80 assertThrows(GeneralSecurityException.class, builder::build); 81 } 82 83 @Test buildParametersWithoutSettingHashType_fails()84 public void buildParametersWithoutSettingHashType_fails() throws Exception { 85 AesGcmHkdfStreamingParameters.Builder builder = 86 AesGcmHkdfStreamingParameters.builder() 87 .setKeySizeBytes(19) 88 .setDerivedAesGcmKeySizeBytes(16) 89 .setCiphertextSegmentSizeBytes(1024 * 1024); 90 assertThrows(GeneralSecurityException.class, builder::build); 91 } 92 93 @Test buildParametersWithoutSettingCiphertextSegmentSize_fails()94 public void buildParametersWithoutSettingCiphertextSegmentSize_fails() throws Exception { 95 AesGcmHkdfStreamingParameters.Builder builder = 96 AesGcmHkdfStreamingParameters.builder() 97 .setKeySizeBytes(19) 98 .setDerivedAesGcmKeySizeBytes(16) 99 .setHkdfHashType(AesGcmHkdfStreamingParameters.HashType.SHA256); 100 assertThrows(GeneralSecurityException.class, builder::build); 101 } 102 103 @Test ciphertextSegmentSizeLowerLimit()104 public void ciphertextSegmentSizeLowerLimit() throws Exception { 105 AesGcmHkdfStreamingParameters.Builder builder = 106 AesGcmHkdfStreamingParameters.builder() 107 .setKeySizeBytes(77) 108 .setDerivedAesGcmKeySizeBytes(32) 109 .setHkdfHashType(AesGcmHkdfStreamingParameters.HashType.SHA1) 110 .setCiphertextSegmentSizeBytes(32 + 24); 111 assertThrows(GeneralSecurityException.class, builder::build); 112 113 Object unused = 114 AesGcmHkdfStreamingParameters.builder() 115 .setKeySizeBytes(77) 116 .setDerivedAesGcmKeySizeBytes(32) 117 .setHkdfHashType(AesGcmHkdfStreamingParameters.HashType.SHA1) 118 .setCiphertextSegmentSizeBytes(32 + 25) 119 .build(); 120 } 121 122 @Test derivedKeySize_fails()123 public void derivedKeySize_fails() throws Exception { 124 AesGcmHkdfStreamingParameters.Builder builder = 125 AesGcmHkdfStreamingParameters.builder() 126 .setKeySizeBytes(77) 127 .setDerivedAesGcmKeySizeBytes(24) 128 .setHkdfHashType(AesGcmHkdfStreamingParameters.HashType.SHA1) 129 .setCiphertextSegmentSizeBytes(3 * 1024 * 1024); 130 assertThrows(GeneralSecurityException.class, builder::build); 131 132 builder = 133 AesGcmHkdfStreamingParameters.builder() 134 .setKeySizeBytes(77) 135 .setDerivedAesGcmKeySizeBytes(17) 136 .setHkdfHashType(AesGcmHkdfStreamingParameters.HashType.SHA1) 137 .setCiphertextSegmentSizeBytes(3 * 1024 * 1024); 138 assertThrows(GeneralSecurityException.class, builder::build); 139 140 builder = 141 AesGcmHkdfStreamingParameters.builder() 142 .setKeySizeBytes(77) 143 .setDerivedAesGcmKeySizeBytes(33) 144 .setHkdfHashType(AesGcmHkdfStreamingParameters.HashType.SHA1) 145 .setCiphertextSegmentSizeBytes(3 * 1024 * 1024); 146 assertThrows(GeneralSecurityException.class, builder::build); 147 } 148 149 @Test keyValueShorterThanDerivedKeySize_fails()150 public void keyValueShorterThanDerivedKeySize_fails() throws Exception { 151 AesGcmHkdfStreamingParameters.Builder builder = 152 AesGcmHkdfStreamingParameters.builder() 153 .setKeySizeBytes(31) 154 .setDerivedAesGcmKeySizeBytes(32) 155 .setHkdfHashType(AesGcmHkdfStreamingParameters.HashType.SHA1) 156 .setCiphertextSegmentSizeBytes(3 * 1024 * 1024); 157 assertThrows(GeneralSecurityException.class, builder::build); 158 159 builder = 160 AesGcmHkdfStreamingParameters.builder() 161 .setKeySizeBytes(15) 162 .setDerivedAesGcmKeySizeBytes(16) 163 .setHkdfHashType(AesGcmHkdfStreamingParameters.HashType.SHA1) 164 .setCiphertextSegmentSizeBytes(3 * 1024 * 1024); 165 assertThrows(GeneralSecurityException.class, builder::build); 166 } 167 168 @Test testNotEqualandNotEqualHashCode()169 public void testNotEqualandNotEqualHashCode() throws Exception { 170 AesGcmHkdfStreamingParameters parameters1 = 171 AesGcmHkdfStreamingParameters.builder() 172 .setKeySizeBytes(35) 173 .setDerivedAesGcmKeySizeBytes(32) 174 .setHkdfHashType(AesGcmHkdfStreamingParameters.HashType.SHA256) 175 .setCiphertextSegmentSizeBytes(1024 * 1024) 176 .build(); 177 178 AesGcmHkdfStreamingParameters parameters2 = 179 AesGcmHkdfStreamingParameters.builder() 180 .setKeySizeBytes(35) 181 .setDerivedAesGcmKeySizeBytes(32) 182 .setHkdfHashType(AesGcmHkdfStreamingParameters.HashType.SHA256) 183 .setCiphertextSegmentSizeBytes(1024 * 1024) 184 .build(); 185 186 assertThat(parameters1).isEqualTo(parameters2); 187 assertThat(parameters1.hashCode()).isEqualTo(parameters2.hashCode()); 188 189 // Different KeySizeBytes 190 parameters2 = 191 AesGcmHkdfStreamingParameters.builder() 192 .setKeySizeBytes(36) 193 .setDerivedAesGcmKeySizeBytes(32) 194 .setHkdfHashType(AesGcmHkdfStreamingParameters.HashType.SHA256) 195 .setCiphertextSegmentSizeBytes(1024 * 1024) 196 .build(); 197 198 assertThat(parameters1).isNotEqualTo(parameters2); 199 assertThat(parameters1.hashCode()).isNotEqualTo(parameters2.hashCode()); 200 201 // Different DerivedAesGcmKeySizeBytes 202 parameters2 = 203 AesGcmHkdfStreamingParameters.builder() 204 .setKeySizeBytes(35) 205 .setDerivedAesGcmKeySizeBytes(16) 206 .setHkdfHashType(AesGcmHkdfStreamingParameters.HashType.SHA256) 207 .setCiphertextSegmentSizeBytes(1024 * 1024) 208 .build(); 209 210 assertThat(parameters1).isNotEqualTo(parameters2); 211 assertThat(parameters1.hashCode()).isNotEqualTo(parameters2.hashCode()); 212 213 // Different hkdf hash type 214 parameters2 = 215 AesGcmHkdfStreamingParameters.builder() 216 .setKeySizeBytes(35) 217 .setDerivedAesGcmKeySizeBytes(32) 218 .setHkdfHashType(AesGcmHkdfStreamingParameters.HashType.SHA1) 219 .setCiphertextSegmentSizeBytes(1024 * 1024) 220 .build(); 221 222 assertThat(parameters1).isNotEqualTo(parameters2); 223 assertThat(parameters1.hashCode()).isNotEqualTo(parameters2.hashCode()); 224 225 // Different ciphertext segment size 226 parameters2 = 227 AesGcmHkdfStreamingParameters.builder() 228 .setKeySizeBytes(35) 229 .setDerivedAesGcmKeySizeBytes(32) 230 .setHkdfHashType(AesGcmHkdfStreamingParameters.HashType.SHA256) 231 .setCiphertextSegmentSizeBytes(1024 * 1024 + 1) 232 .build(); 233 234 assertThat(parameters1).isNotEqualTo(parameters2); 235 assertThat(parameters1.hashCode()).isNotEqualTo(parameters2.hashCode()); 236 } 237 238 @Test 239 @SuppressWarnings("TruthIncompatibleType") testEqualDifferentClass()240 public void testEqualDifferentClass() throws Exception { 241 AesGcmHkdfStreamingParameters parameters = 242 AesGcmHkdfStreamingParameters.builder() 243 .setKeySizeBytes(35) 244 .setDerivedAesGcmKeySizeBytes(32) 245 .setHkdfHashType(AesGcmHkdfStreamingParameters.HashType.SHA256) 246 .setCiphertextSegmentSizeBytes(1024 * 1024) 247 .build(); 248 assertThat(parameters).isNotEqualTo(XChaCha20Poly1305Parameters.create()); 249 } 250 } 251