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 AesCtrHmacStreamingParametersTest { 30 @Test buildParametersAndGetProperties()31 public void buildParametersAndGetProperties() throws Exception { 32 AesCtrHmacStreamingParameters parameters = 33 AesCtrHmacStreamingParameters.builder() 34 .setKeySizeBytes(19) 35 .setDerivedKeySizeBytes(16) 36 .setHkdfHashType(AesCtrHmacStreamingParameters.HashType.SHA256) 37 .setHmacHashType(AesCtrHmacStreamingParameters.HashType.SHA1) 38 .setHmacTagSizeBytes(14) 39 .setCiphertextSegmentSizeBytes(1024 * 1024) 40 .build(); 41 assertThat(parameters.getKeySizeBytes()).isEqualTo(19); 42 assertThat(parameters.getDerivedKeySizeBytes()).isEqualTo(16); 43 assertThat(parameters.getHkdfHashType()) 44 .isEqualTo(AesCtrHmacStreamingParameters.HashType.SHA256); 45 assertThat(parameters.getHmacHashType()).isEqualTo(AesCtrHmacStreamingParameters.HashType.SHA1); 46 assertThat(parameters.getHmacTagSizeBytes()).isEqualTo(14); 47 assertThat(parameters.getCiphertextSegmentSizeBytes()).isEqualTo(1024 * 1024); 48 assertThat(parameters.hasIdRequirement()).isFalse(); 49 } 50 51 @Test buildParametersVariedValues()52 public void buildParametersVariedValues() throws Exception { 53 AesCtrHmacStreamingParameters parameters = 54 AesCtrHmacStreamingParameters.builder() 55 .setKeySizeBytes(35) 56 .setDerivedKeySizeBytes(32) 57 .setHkdfHashType(AesCtrHmacStreamingParameters.HashType.SHA512) 58 .setHmacHashType(AesCtrHmacStreamingParameters.HashType.SHA256) 59 .setHmacTagSizeBytes(16) 60 .setCiphertextSegmentSizeBytes(3 * 1024 * 1024) 61 .build(); 62 assertThat(parameters.getKeySizeBytes()).isEqualTo(35); 63 assertThat(parameters.getDerivedKeySizeBytes()).isEqualTo(32); 64 assertThat(parameters.getHkdfHashType()) 65 .isEqualTo(AesCtrHmacStreamingParameters.HashType.SHA512); 66 assertThat(parameters.getHmacHashType()) 67 .isEqualTo(AesCtrHmacStreamingParameters.HashType.SHA256); 68 assertThat(parameters.getHmacTagSizeBytes()).isEqualTo(16); 69 assertThat(parameters.getCiphertextSegmentSizeBytes()).isEqualTo(3 * 1024 * 1024); 70 assertThat(parameters.hasIdRequirement()).isFalse(); 71 } 72 73 @Test buildParameters_withoutSetKeySize_fails()74 public void buildParameters_withoutSetKeySize_fails() throws Exception { 75 AesCtrHmacStreamingParameters.Builder builder = 76 AesCtrHmacStreamingParameters.builder() 77 .setDerivedKeySizeBytes(32) 78 .setHkdfHashType(AesCtrHmacStreamingParameters.HashType.SHA512) 79 .setHmacHashType(AesCtrHmacStreamingParameters.HashType.SHA256) 80 .setHmacTagSizeBytes(16) 81 .setCiphertextSegmentSizeBytes(3 * 1024 * 1024); 82 assertThrows(GeneralSecurityException.class, builder::build); 83 } 84 85 @Test buildParameters_withoutSetDerivedKeySize_fails()86 public void buildParameters_withoutSetDerivedKeySize_fails() throws Exception { 87 AesCtrHmacStreamingParameters.Builder builder = 88 AesCtrHmacStreamingParameters.builder() 89 .setKeySizeBytes(35) 90 .setHkdfHashType(AesCtrHmacStreamingParameters.HashType.SHA512) 91 .setHmacHashType(AesCtrHmacStreamingParameters.HashType.SHA256) 92 .setHmacTagSizeBytes(16) 93 .setCiphertextSegmentSizeBytes(3 * 1024 * 1024); 94 assertThrows(GeneralSecurityException.class, builder::build); 95 } 96 97 @Test buildParameters_withoutSetHkdfHashType_fails()98 public void buildParameters_withoutSetHkdfHashType_fails() throws Exception { 99 AesCtrHmacStreamingParameters.Builder builder = 100 AesCtrHmacStreamingParameters.builder() 101 .setKeySizeBytes(35) 102 .setDerivedKeySizeBytes(32) 103 .setHmacHashType(AesCtrHmacStreamingParameters.HashType.SHA256) 104 .setHmacTagSizeBytes(16) 105 .setCiphertextSegmentSizeBytes(3 * 1024 * 1024); 106 assertThrows(GeneralSecurityException.class, builder::build); 107 } 108 109 @Test buildParameters_withoutSetHmacHashType_fails()110 public void buildParameters_withoutSetHmacHashType_fails() throws Exception { 111 AesCtrHmacStreamingParameters.Builder builder = 112 AesCtrHmacStreamingParameters.builder() 113 .setKeySizeBytes(35) 114 .setDerivedKeySizeBytes(32) 115 .setHkdfHashType(AesCtrHmacStreamingParameters.HashType.SHA512) 116 .setHmacTagSizeBytes(16) 117 .setCiphertextSegmentSizeBytes(3 * 1024 * 1024); 118 assertThrows(GeneralSecurityException.class, builder::build); 119 } 120 121 @Test buildParameters_withoutSetHmacTagSize_fails()122 public void buildParameters_withoutSetHmacTagSize_fails() throws Exception { 123 AesCtrHmacStreamingParameters.Builder builder = 124 AesCtrHmacStreamingParameters.builder() 125 .setKeySizeBytes(35) 126 .setDerivedKeySizeBytes(32) 127 .setHkdfHashType(AesCtrHmacStreamingParameters.HashType.SHA512) 128 .setHmacHashType(AesCtrHmacStreamingParameters.HashType.SHA256) 129 .setCiphertextSegmentSizeBytes(3 * 1024 * 1024); 130 assertThrows(GeneralSecurityException.class, builder::build); 131 } 132 133 @Test buildParameters_withoutSetCiphertextSegmentSize_fails()134 public void buildParameters_withoutSetCiphertextSegmentSize_fails() throws Exception { 135 AesCtrHmacStreamingParameters.Builder builder = 136 AesCtrHmacStreamingParameters.builder() 137 .setKeySizeBytes(35) 138 .setDerivedKeySizeBytes(32) 139 .setHkdfHashType(AesCtrHmacStreamingParameters.HashType.SHA512) 140 .setHmacHashType(AesCtrHmacStreamingParameters.HashType.SHA256) 141 .setHmacTagSizeBytes(16); 142 assertThrows(GeneralSecurityException.class, builder::build); 143 } 144 145 @Test buildParameters_derivedKeySizeNot16Or32A_throws()146 public void buildParameters_derivedKeySizeNot16Or32A_throws() throws Exception { 147 AesCtrHmacStreamingParameters.Builder builder = 148 AesCtrHmacStreamingParameters.builder() 149 .setKeySizeBytes(35) 150 .setDerivedKeySizeBytes(24) 151 .setHkdfHashType(AesCtrHmacStreamingParameters.HashType.SHA512) 152 .setHmacHashType(AesCtrHmacStreamingParameters.HashType.SHA256) 153 .setHmacTagSizeBytes(16) 154 .setCiphertextSegmentSizeBytes(3 * 1024 * 1024); 155 assertThrows(GeneralSecurityException.class, builder::build); 156 } 157 158 @Test buildParameters_derivedKeySizeNot16Or32B_throws()159 public void buildParameters_derivedKeySizeNot16Or32B_throws() throws Exception { 160 AesCtrHmacStreamingParameters.Builder builder = 161 AesCtrHmacStreamingParameters.builder() 162 .setKeySizeBytes(35) 163 .setDerivedKeySizeBytes(17) 164 .setHkdfHashType(AesCtrHmacStreamingParameters.HashType.SHA512) 165 .setHmacHashType(AesCtrHmacStreamingParameters.HashType.SHA256) 166 .setHmacTagSizeBytes(16) 167 .setCiphertextSegmentSizeBytes(3 * 1024 * 1024); 168 assertThrows(GeneralSecurityException.class, builder::build); 169 } 170 171 @Test buildParameters_ciphertextSegmentSizeLowerBound()172 public void buildParameters_ciphertextSegmentSizeLowerBound() throws Exception { 173 AesCtrHmacStreamingParameters.Builder builder = 174 AesCtrHmacStreamingParameters.builder() 175 .setKeySizeBytes(35) 176 .setDerivedKeySizeBytes(32) 177 .setHkdfHashType(AesCtrHmacStreamingParameters.HashType.SHA512) 178 .setHmacHashType(AesCtrHmacStreamingParameters.HashType.SHA256) 179 .setHmacTagSizeBytes(19) 180 .setCiphertextSegmentSizeBytes(32 + 19 + 8); 181 assertThrows(GeneralSecurityException.class, builder::build); 182 183 builder.setCiphertextSegmentSizeBytes(32 + 19 + 8 + 1); 184 Object unused = builder.build(); 185 } 186 187 @Test buildParameters_ciphertextSegmentSizeLowerBound2()188 public void buildParameters_ciphertextSegmentSizeLowerBound2() throws Exception { 189 AesCtrHmacStreamingParameters.Builder builder = 190 AesCtrHmacStreamingParameters.builder() 191 .setKeySizeBytes(35) 192 .setDerivedKeySizeBytes(16) 193 .setHkdfHashType(AesCtrHmacStreamingParameters.HashType.SHA512) 194 .setHmacHashType(AesCtrHmacStreamingParameters.HashType.SHA256) 195 .setHmacTagSizeBytes(19) 196 .setCiphertextSegmentSizeBytes(16 + 19 + 8); 197 assertThrows(GeneralSecurityException.class, builder::build); 198 199 builder.setCiphertextSegmentSizeBytes(16 + 19 + 8 + 1); 200 Object unused = builder.build(); 201 } 202 203 @Test buildParameters_initialKeymaterialBound1()204 public void buildParameters_initialKeymaterialBound1() throws Exception { 205 AesCtrHmacStreamingParameters.Builder builder = 206 AesCtrHmacStreamingParameters.builder() 207 .setKeySizeBytes(31) 208 .setDerivedKeySizeBytes(32) 209 .setHkdfHashType(AesCtrHmacStreamingParameters.HashType.SHA512) 210 .setHmacHashType(AesCtrHmacStreamingParameters.HashType.SHA256) 211 .setHmacTagSizeBytes(16) 212 .setCiphertextSegmentSizeBytes(3 * 1024 * 1024); 213 assertThrows(GeneralSecurityException.class, builder::build); 214 215 builder.setKeySizeBytes(32); 216 Object unused = builder.build(); 217 } 218 219 @Test buildParameters_initialKeymaterialBound2()220 public void buildParameters_initialKeymaterialBound2() throws Exception { 221 AesCtrHmacStreamingParameters.Builder builder = 222 AesCtrHmacStreamingParameters.builder() 223 .setKeySizeBytes(15) 224 .setDerivedKeySizeBytes(16) 225 .setHkdfHashType(AesCtrHmacStreamingParameters.HashType.SHA512) 226 .setHmacHashType(AesCtrHmacStreamingParameters.HashType.SHA256) 227 .setHmacTagSizeBytes(16) 228 .setCiphertextSegmentSizeBytes(3 * 1024 * 1024); 229 assertThrows(GeneralSecurityException.class, builder::build); 230 231 builder.setKeySizeBytes(16); 232 Object unused = builder.build(); 233 } 234 235 @Test buildParameters_hmacTagSize_SHA1_bounds()236 public void buildParameters_hmacTagSize_SHA1_bounds() throws Exception { 237 AesCtrHmacStreamingParameters.Builder builder = 238 AesCtrHmacStreamingParameters.builder() 239 .setKeySizeBytes(19) 240 .setDerivedKeySizeBytes(16) 241 .setHkdfHashType(AesCtrHmacStreamingParameters.HashType.SHA512) 242 .setHmacHashType(AesCtrHmacStreamingParameters.HashType.SHA1) 243 .setCiphertextSegmentSizeBytes(3 * 1024 * 1024); 244 245 builder.setHmacTagSizeBytes(9); 246 assertThrows(GeneralSecurityException.class, builder::build); 247 248 builder.setHmacTagSizeBytes(10); 249 Object unused = builder.build(); 250 251 builder.setHmacTagSizeBytes(19); 252 unused = builder.build(); 253 254 builder.setHmacTagSizeBytes(20); 255 unused = builder.build(); 256 257 builder.setHmacTagSizeBytes(21); 258 assertThrows(GeneralSecurityException.class, builder::build); 259 } 260 261 @Test buildParameters_hmacTagSize_SHA256_bounds()262 public void buildParameters_hmacTagSize_SHA256_bounds() throws Exception { 263 AesCtrHmacStreamingParameters.Builder builder = 264 AesCtrHmacStreamingParameters.builder() 265 .setKeySizeBytes(19) 266 .setDerivedKeySizeBytes(16) 267 .setHkdfHashType(AesCtrHmacStreamingParameters.HashType.SHA512) 268 .setHmacHashType(AesCtrHmacStreamingParameters.HashType.SHA256) 269 .setCiphertextSegmentSizeBytes(3 * 1024 * 1024); 270 271 builder.setHmacTagSizeBytes(9); 272 assertThrows(GeneralSecurityException.class, builder::build); 273 274 builder.setHmacTagSizeBytes(10); 275 Object unused = builder.build(); 276 277 builder.setHmacTagSizeBytes(31); 278 unused = builder.build(); 279 280 builder.setHmacTagSizeBytes(32); 281 unused = builder.build(); 282 283 builder.setHmacTagSizeBytes(33); 284 assertThrows(GeneralSecurityException.class, builder::build); 285 } 286 287 @Test buildParameters_hmacTagSize_SHA512_bounds()288 public void buildParameters_hmacTagSize_SHA512_bounds() throws Exception { 289 AesCtrHmacStreamingParameters.Builder builder = 290 AesCtrHmacStreamingParameters.builder() 291 .setKeySizeBytes(19) 292 .setDerivedKeySizeBytes(16) 293 .setHkdfHashType(AesCtrHmacStreamingParameters.HashType.SHA1) 294 .setHmacHashType(AesCtrHmacStreamingParameters.HashType.SHA512) 295 .setCiphertextSegmentSizeBytes(3 * 1024 * 1024); 296 297 builder.setHmacTagSizeBytes(9); 298 assertThrows(GeneralSecurityException.class, builder::build); 299 300 builder.setHmacTagSizeBytes(10); 301 Object unused = builder.build(); 302 303 builder.setHmacTagSizeBytes(63); 304 unused = builder.build(); 305 306 builder.setHmacTagSizeBytes(64); 307 unused = builder.build(); 308 309 builder.setHmacTagSizeBytes(65); 310 assertThrows(GeneralSecurityException.class, builder::build); 311 } 312 313 @Test testNotEqualandNotEqualHashCode()314 public void testNotEqualandNotEqualHashCode() throws Exception { 315 AesCtrHmacStreamingParameters parameters1 = 316 AesCtrHmacStreamingParameters.builder() 317 .setKeySizeBytes(33) 318 .setDerivedKeySizeBytes(16) 319 .setHkdfHashType(AesCtrHmacStreamingParameters.HashType.SHA256) 320 .setHmacHashType(AesCtrHmacStreamingParameters.HashType.SHA1) 321 .setHmacTagSizeBytes(14) 322 .setCiphertextSegmentSizeBytes(1024 * 1024) 323 .build(); 324 325 AesCtrHmacStreamingParameters parameters2 = 326 AesCtrHmacStreamingParameters.builder() 327 .setKeySizeBytes(33) 328 .setDerivedKeySizeBytes(16) 329 .setHkdfHashType(AesCtrHmacStreamingParameters.HashType.SHA256) 330 .setHmacHashType(AesCtrHmacStreamingParameters.HashType.SHA1) 331 .setHmacTagSizeBytes(14) 332 .setCiphertextSegmentSizeBytes(1024 * 1024) 333 .build(); 334 335 assertThat(parameters1).isEqualTo(parameters2); 336 assertThat(parameters1.hashCode()).isEqualTo(parameters2.hashCode()); 337 338 // Different KeySizeBytes 339 parameters2 = 340 AesCtrHmacStreamingParameters.builder() 341 .setKeySizeBytes(32) 342 .setDerivedKeySizeBytes(16) 343 .setHkdfHashType(AesCtrHmacStreamingParameters.HashType.SHA256) 344 .setHmacHashType(AesCtrHmacStreamingParameters.HashType.SHA1) 345 .setHmacTagSizeBytes(14) 346 .setCiphertextSegmentSizeBytes(1024 * 1024) 347 .build(); 348 349 assertThat(parameters1).isNotEqualTo(parameters2); 350 assertThat(parameters1.hashCode()).isNotEqualTo(parameters2.hashCode()); 351 352 // Different DerivedKeySizeBytes 353 parameters2 = 354 AesCtrHmacStreamingParameters.builder() 355 .setKeySizeBytes(33) 356 .setDerivedKeySizeBytes(32) 357 .setHkdfHashType(AesCtrHmacStreamingParameters.HashType.SHA256) 358 .setHmacHashType(AesCtrHmacStreamingParameters.HashType.SHA1) 359 .setHmacTagSizeBytes(14) 360 .setCiphertextSegmentSizeBytes(1024 * 1024) 361 .build(); 362 363 assertThat(parameters1).isNotEqualTo(parameters2); 364 assertThat(parameters1.hashCode()).isNotEqualTo(parameters2.hashCode()); 365 366 // Different HkdfHashType 367 parameters2 = 368 AesCtrHmacStreamingParameters.builder() 369 .setKeySizeBytes(33) 370 .setDerivedKeySizeBytes(16) 371 .setHkdfHashType(AesCtrHmacStreamingParameters.HashType.SHA512) 372 .setHmacHashType(AesCtrHmacStreamingParameters.HashType.SHA1) 373 .setHmacTagSizeBytes(14) 374 .setCiphertextSegmentSizeBytes(1024 * 1024) 375 .build(); 376 377 assertThat(parameters1).isNotEqualTo(parameters2); 378 assertThat(parameters1.hashCode()).isNotEqualTo(parameters2.hashCode()); 379 380 // Different HmacHashType 381 parameters2 = 382 AesCtrHmacStreamingParameters.builder() 383 .setKeySizeBytes(33) 384 .setDerivedKeySizeBytes(16) 385 .setHkdfHashType(AesCtrHmacStreamingParameters.HashType.SHA256) 386 .setHmacHashType(AesCtrHmacStreamingParameters.HashType.SHA512) 387 .setHmacTagSizeBytes(14) 388 .setCiphertextSegmentSizeBytes(1024 * 1024) 389 .build(); 390 391 assertThat(parameters1).isNotEqualTo(parameters2); 392 assertThat(parameters1.hashCode()).isNotEqualTo(parameters2.hashCode()); 393 394 // Different HmacTagSizeBytes 395 parameters2 = 396 AesCtrHmacStreamingParameters.builder() 397 .setKeySizeBytes(33) 398 .setDerivedKeySizeBytes(16) 399 .setHkdfHashType(AesCtrHmacStreamingParameters.HashType.SHA256) 400 .setHmacHashType(AesCtrHmacStreamingParameters.HashType.SHA1) 401 .setHmacTagSizeBytes(15) 402 .setCiphertextSegmentSizeBytes(1024 * 1024) 403 .build(); 404 405 assertThat(parameters1).isNotEqualTo(parameters2); 406 assertThat(parameters1.hashCode()).isNotEqualTo(parameters2.hashCode()); 407 408 // Different CiphertextSegmentSize 409 parameters2 = 410 AesCtrHmacStreamingParameters.builder() 411 .setKeySizeBytes(33) 412 .setDerivedKeySizeBytes(16) 413 .setHkdfHashType(AesCtrHmacStreamingParameters.HashType.SHA256) 414 .setHmacHashType(AesCtrHmacStreamingParameters.HashType.SHA1) 415 .setHmacTagSizeBytes(14) 416 .setCiphertextSegmentSizeBytes(3 * 1024 * 1024) 417 .build(); 418 419 assertThat(parameters1).isNotEqualTo(parameters2); 420 assertThat(parameters1.hashCode()).isNotEqualTo(parameters2.hashCode()); 421 } 422 423 @Test 424 @SuppressWarnings("TruthIncompatibleType") testEqualDifferentClass()425 public void testEqualDifferentClass() throws Exception { 426 AesCtrHmacStreamingParameters parameters = 427 AesCtrHmacStreamingParameters.builder() 428 .setKeySizeBytes(19) 429 .setDerivedKeySizeBytes(16) 430 .setHkdfHashType(AesCtrHmacStreamingParameters.HashType.SHA256) 431 .setHmacHashType(AesCtrHmacStreamingParameters.HashType.SHA1) 432 .setHmacTagSizeBytes(14) 433 .setCiphertextSegmentSizeBytes(1024 * 1024) 434 .build(); 435 assertThat(parameters).isNotEqualTo(XChaCha20Poly1305Parameters.create()); 436 } 437 } 438