1 // Copyright 2022 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.aead; 18 19 import static com.google.common.truth.Truth.assertThat; 20 import static org.junit.Assert.assertThrows; 21 22 import com.google.crypto.tink.InsecureSecretKeyAccess; 23 import com.google.crypto.tink.internal.KeyTester; 24 import com.google.crypto.tink.subtle.Hex; 25 import com.google.crypto.tink.util.Bytes; 26 import com.google.crypto.tink.util.SecretBytes; 27 import java.security.GeneralSecurityException; 28 import org.junit.Test; 29 import org.junit.runner.RunWith; 30 import org.junit.runners.JUnit4; 31 32 @RunWith(JUnit4.class) 33 public final class AesEaxKeyTest { 34 35 @Test buildNoPrefixVariantAndGetProperties()36 public void buildNoPrefixVariantAndGetProperties() throws Exception { 37 AesEaxParameters parameters = 38 AesEaxParameters.builder() 39 .setKeySizeBytes(16) 40 .setIvSizeBytes(16) 41 .setTagSizeBytes(16) 42 .setVariant(AesEaxParameters.Variant.NO_PREFIX) 43 .build(); 44 assertThat(parameters.hasIdRequirement()).isFalse(); 45 SecretBytes keyBytes = SecretBytes.randomBytes(16); 46 AesEaxKey key = AesEaxKey.builder().setParameters(parameters).setKeyBytes(keyBytes).build(); 47 assertThat(key.getParameters()).isEqualTo(parameters); 48 assertThat(key.getKeyBytes()).isEqualTo(keyBytes); 49 assertThat(key.getOutputPrefix()).isEqualTo(Bytes.copyFrom(new byte[] {})); 50 assertThat(key.getIdRequirementOrNull()).isNull(); 51 } 52 53 @Test buildTinkVariantAndGetProperties()54 public void buildTinkVariantAndGetProperties() throws Exception { 55 AesEaxParameters parameters = 56 AesEaxParameters.builder() 57 .setKeySizeBytes(16) 58 .setIvSizeBytes(16) 59 .setTagSizeBytes(16) 60 .setVariant(AesEaxParameters.Variant.TINK) 61 .build(); 62 assertThat(parameters.hasIdRequirement()).isTrue(); 63 SecretBytes keyBytes = SecretBytes.randomBytes(16); 64 AesEaxKey key = 65 AesEaxKey.builder() 66 .setParameters(parameters) 67 .setKeyBytes(keyBytes) 68 .setIdRequirement(0x66AABBCC) 69 .build(); 70 assertThat(key.getParameters()).isEqualTo(parameters); 71 assertThat(key.getKeyBytes()).isEqualTo(keyBytes); 72 assertThat(key.getOutputPrefix()).isEqualTo(Bytes.copyFrom(Hex.decode("0166AABBCC"))); 73 assertThat(key.getIdRequirementOrNull()).isEqualTo(0x66AABBCC); 74 } 75 76 @Test buildCrunchyVariantAndGetProperties()77 public void buildCrunchyVariantAndGetProperties() throws Exception { 78 AesEaxParameters parameters = 79 AesEaxParameters.builder() 80 .setKeySizeBytes(16) 81 .setIvSizeBytes(16) 82 .setTagSizeBytes(16) 83 .setVariant(AesEaxParameters.Variant.CRUNCHY) 84 .build(); 85 assertThat(parameters.hasIdRequirement()).isTrue(); 86 SecretBytes keyBytes = SecretBytes.randomBytes(16); 87 AesEaxKey key = 88 AesEaxKey.builder() 89 .setParameters(parameters) 90 .setKeyBytes(keyBytes) 91 .setIdRequirement(0x66AABBCC) 92 .build(); 93 assertThat(key.getParameters()).isEqualTo(parameters); 94 assertThat(key.getKeyBytes()).isEqualTo(keyBytes); 95 assertThat(key.getOutputPrefix()).isEqualTo(Bytes.copyFrom(Hex.decode("0066AABBCC"))); 96 assertThat(key.getIdRequirementOrNull()).isEqualTo(0x66AABBCC); 97 } 98 99 @Test emptyBuild_fails()100 public void emptyBuild_fails() throws Exception { 101 assertThrows(GeneralSecurityException.class, () -> AesEaxKey.builder().build()); 102 } 103 104 @Test buildWithoutParameters_fails()105 public void buildWithoutParameters_fails() throws Exception { 106 assertThrows( 107 GeneralSecurityException.class, 108 () -> AesEaxKey.builder().setKeyBytes(SecretBytes.randomBytes(32)).build()); 109 } 110 111 @Test buildWithoutKeyBytes_fails()112 public void buildWithoutKeyBytes_fails() throws Exception { 113 AesEaxParameters parameters = 114 AesEaxParameters.builder() 115 .setKeySizeBytes(16) 116 .setIvSizeBytes(12) 117 .setTagSizeBytes(16) 118 .setVariant(AesEaxParameters.Variant.NO_PREFIX) 119 .build(); 120 assertThrows( 121 GeneralSecurityException.class, 122 () -> AesEaxKey.builder().setParameters(parameters).build()); 123 } 124 125 @Test paramtersRequireIdButIdIsNotSetInBuild_fails()126 public void paramtersRequireIdButIdIsNotSetInBuild_fails() throws Exception { 127 AesEaxParameters parametersWithIdRequirement = 128 AesEaxParameters.builder() 129 .setKeySizeBytes(16) 130 .setIvSizeBytes(12) 131 .setTagSizeBytes(16) 132 .setVariant(AesEaxParameters.Variant.TINK) 133 .build(); 134 assertThat(parametersWithIdRequirement.hasIdRequirement()).isTrue(); 135 assertThrows( 136 GeneralSecurityException.class, 137 () -> 138 AesEaxKey.builder() 139 .setKeyBytes(SecretBytes.randomBytes(16)) 140 .setParameters(parametersWithIdRequirement) 141 .build()); 142 } 143 144 @Test build_keyTooSmall_fails()145 public void build_keyTooSmall_fails() throws Exception { 146 AesEaxParameters parameters = 147 AesEaxParameters.builder() 148 .setKeySizeBytes(32) 149 .setIvSizeBytes(12) 150 .setTagSizeBytes(16) 151 .setVariant(AesEaxParameters.Variant.NO_PREFIX) 152 .build(); 153 assertThrows( 154 GeneralSecurityException.class, 155 () -> 156 AesEaxKey.builder() 157 .setParameters(parameters) 158 .setKeyBytes(SecretBytes.randomBytes(16)) 159 .build()); 160 } 161 162 @Test build_keyTooLarge_fails()163 public void build_keyTooLarge_fails() throws Exception { 164 AesEaxParameters parameters = 165 AesEaxParameters.builder() 166 .setKeySizeBytes(16) 167 .setIvSizeBytes(12) 168 .setTagSizeBytes(16) 169 .setVariant(AesEaxParameters.Variant.NO_PREFIX) 170 .build(); 171 assertThrows( 172 GeneralSecurityException.class, 173 () -> 174 AesEaxKey.builder() 175 .setParameters(parameters) 176 .setKeyBytes(SecretBytes.randomBytes(32)) 177 .build()); 178 } 179 180 @Test testEqualities()181 public void testEqualities() throws Exception { 182 SecretBytes keyBytes32 = SecretBytes.randomBytes(32); 183 SecretBytes keyBytes32Copy = 184 SecretBytes.copyFrom( 185 keyBytes32.toByteArray(InsecureSecretKeyAccess.get()), InsecureSecretKeyAccess.get()); 186 SecretBytes keyBytes32Diff = SecretBytes.randomBytes(32); 187 SecretBytes keyBytes16 = SecretBytes.randomBytes(16); 188 189 AesEaxParameters noPrefixParametersKeySize32 = 190 AesEaxParameters.builder() 191 .setKeySizeBytes(32) 192 .setIvSizeBytes(12) 193 .setTagSizeBytes(16) 194 .setVariant(AesEaxParameters.Variant.NO_PREFIX) 195 .build(); 196 AesEaxParameters noPrefixParametersKeySize16 = 197 AesEaxParameters.builder() 198 .setKeySizeBytes(16) 199 .setIvSizeBytes(12) 200 .setTagSizeBytes(16) 201 .setVariant(AesEaxParameters.Variant.NO_PREFIX) 202 .build(); 203 AesEaxParameters noPrefixParametersKeySize32IvSize16 = 204 AesEaxParameters.builder() 205 .setKeySizeBytes(32) 206 .setIvSizeBytes(16) 207 .setTagSizeBytes(16) 208 .setVariant(AesEaxParameters.Variant.NO_PREFIX) 209 .build(); 210 AesEaxParameters tinkPrefixParametersKeySize32 = 211 AesEaxParameters.builder() 212 .setKeySizeBytes(32) 213 .setIvSizeBytes(12) 214 .setTagSizeBytes(16) 215 .setVariant(AesEaxParameters.Variant.TINK) 216 .build(); 217 AesEaxParameters crunchyPrefixParametersKeySize32 = 218 AesEaxParameters.builder() 219 .setKeySizeBytes(32) 220 .setIvSizeBytes(12) 221 .setTagSizeBytes(16) 222 .setVariant(AesEaxParameters.Variant.CRUNCHY) 223 .build(); 224 new KeyTester() 225 .addEqualityGroup( 226 "No prefix, keyBytes32", 227 AesEaxKey.builder() 228 .setParameters(noPrefixParametersKeySize32) 229 .setKeyBytes(keyBytes32) 230 .build(), 231 // The same key built twice must be equal. 232 AesEaxKey.builder() 233 .setParameters(noPrefixParametersKeySize32) 234 .setKeyBytes(keyBytes32) 235 .build(), 236 // The same key built with a copy of key bytes must be equal. 237 AesEaxKey.builder() 238 .setParameters(noPrefixParametersKeySize32) 239 .setKeyBytes(keyBytes32Copy) 240 .build(), 241 // Setting id requirement to null is equal to not setting it. 242 AesEaxKey.builder() 243 .setParameters(noPrefixParametersKeySize32) 244 .setKeyBytes(keyBytes32) 245 .setIdRequirement(null) 246 .build()) 247 // This group checks that keys with different key bytes are not equal. 248 .addEqualityGroup( 249 "No prefix, newly generated keyBytes32", 250 AesEaxKey.builder() 251 .setParameters(noPrefixParametersKeySize32) 252 .setKeyBytes(keyBytes32Diff) 253 .build()) 254 // This group checks that keys with different IV sizes are not equal. 255 .addEqualityGroup( 256 "No prefix with IV size 16, keyBytes32", 257 AesEaxKey.builder() 258 .setParameters(noPrefixParametersKeySize32IvSize16) 259 .setKeyBytes(keyBytes32) 260 .build()) 261 // This group checks that keys with different key sizes are not equal. 262 .addEqualityGroup( 263 "No prefix, keyBytes16", 264 AesEaxKey.builder() 265 .setParameters(noPrefixParametersKeySize16) 266 .setKeyBytes(keyBytes16) 267 .build()) 268 .addEqualityGroup( 269 "Tink with key id 1907, keyBytes32", 270 AesEaxKey.builder() 271 .setParameters(tinkPrefixParametersKeySize32) 272 .setKeyBytes(keyBytes32) 273 .setIdRequirement(1907) 274 .build(), 275 AesEaxKey.builder() 276 .setParameters(tinkPrefixParametersKeySize32) 277 .setKeyBytes(keyBytes32Copy) 278 .setIdRequirement(1907) 279 .build()) 280 // This group checks that keys with different key ids are not equal. 281 .addEqualityGroup( 282 "Tink with key id 1908, keyBytes32", 283 AesEaxKey.builder() 284 .setParameters(tinkPrefixParametersKeySize32) 285 .setKeyBytes(keyBytes32) 286 .setIdRequirement(1908) 287 .build()) 288 // This groups checks that keys with different output prefix types are not equal. 289 .addEqualityGroup( 290 "Crunchy with key id 1907, keyBytes32", 291 AesEaxKey.builder() 292 .setParameters(crunchyPrefixParametersKeySize32) 293 .setKeyBytes(keyBytes32) 294 .setIdRequirement(1907) 295 .build()) 296 .doTests(); 297 } 298 } 299