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.mac; 18 19 import static com.google.common.truth.Truth.assertThat; 20 import static org.junit.Assert.assertThrows; 21 22 import com.google.errorprone.annotations.CanIgnoreReturnValue; 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 AesCmacParametersTest { 30 private static final AesCmacParameters.Variant NO_PREFIX = AesCmacParameters.Variant.NO_PREFIX; 31 private static final AesCmacParameters.Variant TINK = AesCmacParameters.Variant.TINK; 32 private static final AesCmacParameters.Variant LEGACY = AesCmacParameters.Variant.LEGACY; 33 private static final AesCmacParameters.Variant CRUNCHY = AesCmacParameters.Variant.CRUNCHY; 34 35 @CanIgnoreReturnValue create( int keySizeBytes, int tagSizeBytes, AesCmacParameters.Variant variant)36 private static AesCmacParameters create( 37 int keySizeBytes, int tagSizeBytes, AesCmacParameters.Variant variant) 38 throws GeneralSecurityException { 39 return AesCmacParameters.builder() 40 .setKeySizeBytes(keySizeBytes) 41 .setTagSizeBytes(tagSizeBytes) 42 .setVariant(variant) 43 .build(); 44 } 45 46 @CanIgnoreReturnValue create(int keySizeBytes, int tagSizeBytes)47 private static AesCmacParameters create(int keySizeBytes, int tagSizeBytes) 48 throws GeneralSecurityException { 49 return AesCmacParameters.builder() 50 .setKeySizeBytes(keySizeBytes) 51 .setTagSizeBytes(tagSizeBytes) 52 .build(); 53 } 54 55 @Test testAesCmacParameters_incompleteBuildsFail()56 public void testAesCmacParameters_incompleteBuildsFail() throws Exception { 57 assertThrows(GeneralSecurityException.class, () -> AesCmacParameters.builder().build()); 58 assertThrows( 59 GeneralSecurityException.class, 60 () -> AesCmacParameters.builder().setTagSizeBytes(10).build()); 61 assertThrows( 62 GeneralSecurityException.class, 63 () -> AesCmacParameters.builder().setKeySizeBytes(16).build()); 64 } 65 66 @Test testAesCmacParameters_buildWithVariantSetToNull_fails()67 public void testAesCmacParameters_buildWithVariantSetToNull_fails() throws Exception { 68 assertThrows( 69 GeneralSecurityException.class, 70 () -> 71 AesCmacParameters.builder() 72 .setKeySizeBytes(16) 73 .setTagSizeBytes(16) 74 .setVariant(null) 75 .build()); 76 } 77 78 @Test testAesCmacParameters_basic()79 public void testAesCmacParameters_basic() throws Exception { 80 AesCmacParameters parameters = create(16, 16); 81 assertThat(parameters.getKeySizeBytes()).isEqualTo(16); 82 assertThat(parameters.getCryptographicTagSizeBytes()).isEqualTo(16); 83 assertThat(parameters.getTotalTagSizeBytes()).isEqualTo(16); 84 assertThat(parameters.getVariant()).isEqualTo(NO_PREFIX); 85 assertThat(parameters.hasIdRequirement()).isFalse(); 86 } 87 88 @Test testAesCmacParameters_variant()89 public void testAesCmacParameters_variant() throws Exception { 90 assertThat(create(16, 16, NO_PREFIX).getVariant()).isEqualTo(NO_PREFIX); 91 assertThat(create(16, 16, TINK).getVariant()).isEqualTo(TINK); 92 assertThat(create(16, 16, LEGACY).getVariant()).isEqualTo(LEGACY); 93 assertThat(create(16, 16, CRUNCHY).getVariant()).isEqualTo(CRUNCHY); 94 } 95 96 @Test testAesCmacParameters_hasIdRequirement()97 public void testAesCmacParameters_hasIdRequirement() throws Exception { 98 assertThat(create(32, 16, NO_PREFIX).hasIdRequirement()).isFalse(); 99 assertThat(create(32, 16, TINK).hasIdRequirement()).isTrue(); 100 assertThat(create(32, 16, LEGACY).hasIdRequirement()).isTrue(); 101 assertThat(create(32, 16, CRUNCHY).hasIdRequirement()).isTrue(); 102 } 103 104 @Test testAesCmacParameters_createWithDifferentKeySizes()105 public void testAesCmacParameters_createWithDifferentKeySizes() throws Exception { 106 create(16, 13); 107 create(32, 13); 108 109 assertThrows(GeneralSecurityException.class, () -> create(-2, 13)); 110 assertThrows(GeneralSecurityException.class, () -> create(5, 13)); 111 assertThrows(GeneralSecurityException.class, () -> create(13, 13)); 112 assertThrows(GeneralSecurityException.class, () -> create(20, 13)); 113 assertThrows(GeneralSecurityException.class, () -> create(24, 13)); 114 assertThrows(GeneralSecurityException.class, () -> create(42, 13)); 115 } 116 117 @Test testAesCmacParameters_createForKeysetWithDifferentKeySizes()118 public void testAesCmacParameters_createForKeysetWithDifferentKeySizes() throws Exception { 119 create(16, 13, LEGACY); 120 create(32, 13, CRUNCHY); 121 122 assertThrows(GeneralSecurityException.class, () -> create(-2, 13, LEGACY)); 123 assertThrows(GeneralSecurityException.class, () -> create(5, 13, CRUNCHY)); 124 assertThrows(GeneralSecurityException.class, () -> create(13, 13, TINK)); 125 assertThrows(GeneralSecurityException.class, () -> create(20, 13, LEGACY)); 126 assertThrows(GeneralSecurityException.class, () -> create(24, 13, CRUNCHY)); 127 assertThrows(GeneralSecurityException.class, () -> create(42, 13, TINK)); 128 } 129 130 @Test testAesCmacParameters_getKeySizeBytes()131 public void testAesCmacParameters_getKeySizeBytes() throws Exception { 132 assertThat(create(16, 16).getKeySizeBytes()).isEqualTo(16); 133 assertThat(create(32, 16).getKeySizeBytes()).isEqualTo(32); 134 } 135 136 @Test testAesCmacParameters_tagSizesConstruction()137 public void testAesCmacParameters_tagSizesConstruction() throws Exception { 138 assertThrows(GeneralSecurityException.class, () -> create(16, 5)); 139 assertThrows(GeneralSecurityException.class, () -> create(32, 6)); 140 assertThrows(GeneralSecurityException.class, () -> create(16, 7)); 141 assertThrows(GeneralSecurityException.class, () -> create(32, 8)); 142 assertThrows(GeneralSecurityException.class, () -> create(16, 9)); 143 create(16, 10); 144 create(32, 11); 145 create(16, 12); 146 create(32, 13); 147 create(16, 14); 148 create(32, 15); 149 create(16, 16); 150 assertThrows(GeneralSecurityException.class, () -> create(16, 17)); 151 assertThrows(GeneralSecurityException.class, () -> create(32, 18)); 152 assertThrows(GeneralSecurityException.class, () -> create(16, 19)); 153 assertThrows(GeneralSecurityException.class, () -> create(32, 20)); 154 assertThrows(GeneralSecurityException.class, () -> create(16, 21)); 155 assertThrows(GeneralSecurityException.class, () -> create(32, 32)); 156 } 157 158 @Test testAesCmacParameters_tagSizesConstruction2()159 public void testAesCmacParameters_tagSizesConstruction2() throws Exception { 160 assertThrows(GeneralSecurityException.class, () -> create(32, 5, TINK)); 161 assertThrows(GeneralSecurityException.class, () -> create(16, 6, TINK)); 162 assertThrows(GeneralSecurityException.class, () -> create(32, 7, TINK)); 163 assertThrows(GeneralSecurityException.class, () -> create(16, 8, TINK)); 164 assertThrows(GeneralSecurityException.class, () -> create(32, 9, TINK)); 165 assertThrows(GeneralSecurityException.class, () -> create(16, 9, CRUNCHY)); 166 assertThrows(GeneralSecurityException.class, () -> create(32, 9, LEGACY)); 167 create(16, 10, TINK); 168 create(32, 10, CRUNCHY); 169 create(16, 10, LEGACY); 170 create(32, 11, TINK); 171 create(16, 12, TINK); 172 create(32, 13, TINK); 173 create(16, 14, TINK); 174 create(32, 15, TINK); 175 create(16, 16, TINK); 176 create(32, 16, CRUNCHY); 177 create(16, 16, LEGACY); 178 assertThrows(GeneralSecurityException.class, () -> create(32, 17, CRUNCHY)); 179 assertThrows(GeneralSecurityException.class, () -> create(16, 17, LEGACY)); 180 assertThrows(GeneralSecurityException.class, () -> create(32, 17, TINK)); 181 assertThrows(GeneralSecurityException.class, () -> create(16, 18, TINK)); 182 assertThrows(GeneralSecurityException.class, () -> create(32, 21, TINK)); 183 assertThrows(GeneralSecurityException.class, () -> create(16, 32, TINK)); 184 } 185 186 @Test testAesCmacParameters_getTotalTagSizeBytes()187 public void testAesCmacParameters_getTotalTagSizeBytes() throws Exception { 188 assertThat(create(16, 10).getTotalTagSizeBytes()).isEqualTo(10); 189 assertThat(create(16, 11).getTotalTagSizeBytes()).isEqualTo(11); 190 assertThat(create(16, 12).getTotalTagSizeBytes()).isEqualTo(12); 191 assertThat(create(16, 13).getTotalTagSizeBytes()).isEqualTo(13); 192 assertThat(create(16, 14).getTotalTagSizeBytes()).isEqualTo(14); 193 assertThat(create(16, 15).getTotalTagSizeBytes()).isEqualTo(15); 194 assertThat(create(16, 16).getTotalTagSizeBytes()).isEqualTo(16); 195 assertThat(create(32, 10, TINK).getTotalTagSizeBytes()).isEqualTo(15); 196 assertThat(create(32, 10, CRUNCHY).getTotalTagSizeBytes()).isEqualTo(15); 197 assertThat(create(32, 10, LEGACY).getTotalTagSizeBytes()).isEqualTo(15); 198 assertThat(create(32, 13, TINK).getTotalTagSizeBytes()).isEqualTo(18); 199 assertThat(create(32, 13, CRUNCHY).getTotalTagSizeBytes()).isEqualTo(18); 200 assertThat(create(32, 13, LEGACY).getTotalTagSizeBytes()).isEqualTo(18); 201 assertThat(create(32, 16, TINK).getTotalTagSizeBytes()).isEqualTo(21); 202 assertThat(create(32, 16, CRUNCHY).getTotalTagSizeBytes()).isEqualTo(21); 203 assertThat(create(32, 16, LEGACY).getTotalTagSizeBytes()).isEqualTo(21); 204 } 205 206 @Test testAesCmacParameters_getCryptographicTagSizeBytes()207 public void testAesCmacParameters_getCryptographicTagSizeBytes() throws Exception { 208 assertThat(create(16, 10).getCryptographicTagSizeBytes()).isEqualTo(10); 209 assertThat(create(16, 11).getCryptographicTagSizeBytes()).isEqualTo(11); 210 assertThat(create(16, 12).getCryptographicTagSizeBytes()).isEqualTo(12); 211 assertThat(create(16, 13).getCryptographicTagSizeBytes()).isEqualTo(13); 212 assertThat(create(16, 14).getCryptographicTagSizeBytes()).isEqualTo(14); 213 assertThat(create(16, 15).getCryptographicTagSizeBytes()).isEqualTo(15); 214 assertThat(create(16, 16).getCryptographicTagSizeBytes()).isEqualTo(16); 215 assertThat(create(32, 10, TINK).getCryptographicTagSizeBytes()).isEqualTo(10); 216 assertThat(create(32, 10, CRUNCHY).getCryptographicTagSizeBytes()).isEqualTo(10); 217 assertThat(create(32, 10, LEGACY).getCryptographicTagSizeBytes()).isEqualTo(10); 218 assertThat(create(32, 13, TINK).getCryptographicTagSizeBytes()).isEqualTo(13); 219 assertThat(create(32, 13, CRUNCHY).getCryptographicTagSizeBytes()).isEqualTo(13); 220 assertThat(create(32, 13, LEGACY).getCryptographicTagSizeBytes()).isEqualTo(13); 221 assertThat(create(32, 16, TINK).getCryptographicTagSizeBytes()).isEqualTo(16); 222 assertThat(create(32, 16, CRUNCHY).getCryptographicTagSizeBytes()).isEqualTo(16); 223 assertThat(create(32, 16, LEGACY).getCryptographicTagSizeBytes()).isEqualTo(16); 224 } 225 226 @Test testAesCmacParameters_equal()227 public void testAesCmacParameters_equal() throws Exception { 228 assertThat(create(16, 10)).isEqualTo(create(16, 10, NO_PREFIX)); 229 assertThat(create(32, 11)).isEqualTo(create(32, 11, NO_PREFIX)); 230 assertThat(create(16, 12)).isEqualTo(create(16, 12, NO_PREFIX)); 231 assertThat(create(32, 13)).isEqualTo(create(32, 13, NO_PREFIX)); 232 assertThat(create(16, 13)).isEqualTo(create(16, 13, NO_PREFIX)); 233 assertThat(create(16, 16, TINK)).isEqualTo(create(16, 16, TINK)); 234 assertThat(create(32, 16, LEGACY)).isEqualTo(create(32, 16, LEGACY)); 235 assertThat(create(16, 16, CRUNCHY)).isEqualTo(create(16, 16, CRUNCHY)); 236 } 237 238 @Test testAesCmacParameters_notEqual()239 public void testAesCmacParameters_notEqual() throws Exception { 240 assertThat(create(32, 10, NO_PREFIX)).isNotEqualTo(create(16, 10, NO_PREFIX)); 241 assertThat(create(16, 10, NO_PREFIX)).isNotEqualTo(create(16, 11, NO_PREFIX)); 242 assertThat(create(32, 10, NO_PREFIX)).isNotEqualTo(create(32, 10, TINK)); 243 assertThat(create(16, 10, TINK)).isNotEqualTo(create(16, 10, LEGACY)); 244 assertThat(create(32, 10, LEGACY)).isNotEqualTo(create(32, 10, CRUNCHY)); 245 } 246 247 @Test testAesCmacParameters_equalHashes()248 public void testAesCmacParameters_equalHashes() throws Exception { 249 assertThat(create(16, 10).hashCode()).isEqualTo(create(16, 10, NO_PREFIX).hashCode()); 250 assertThat(create(32, 11).hashCode()).isEqualTo(create(32, 11, NO_PREFIX).hashCode()); 251 assertThat(create(16, 12).hashCode()).isEqualTo(create(16, 12, NO_PREFIX).hashCode()); 252 assertThat(create(32, 13).hashCode()).isEqualTo(create(32, 13, NO_PREFIX).hashCode()); 253 assertThat(create(16, 13).hashCode()).isEqualTo(create(16, 13, NO_PREFIX).hashCode()); 254 assertThat(create(16, 16, TINK).hashCode()).isEqualTo(create(16, 16, TINK).hashCode()); 255 assertThat(create(32, 16, LEGACY).hashCode()).isEqualTo(create(32, 16, LEGACY).hashCode()); 256 assertThat(create(16, 16, CRUNCHY).hashCode()).isEqualTo(create(16, 16, CRUNCHY).hashCode()); 257 } 258 259 @Test testAesCmacParameters_notEqualHashes()260 public void testAesCmacParameters_notEqualHashes() throws Exception { 261 assertThat(create(32, 10, NO_PREFIX).hashCode()) 262 .isNotEqualTo(create(16, 10, NO_PREFIX).hashCode()); 263 assertThat(create(16, 10, NO_PREFIX).hashCode()) 264 .isNotEqualTo(create(16, 11, NO_PREFIX).hashCode()); 265 assertThat(create(32, 10, NO_PREFIX).hashCode()).isNotEqualTo(create(32, 10, TINK).hashCode()); 266 assertThat(create(16, 10, TINK).hashCode()).isNotEqualTo(create(16, 10, LEGACY).hashCode()); 267 assertThat(create(32, 10, LEGACY).hashCode()).isNotEqualTo(create(32, 10, CRUNCHY).hashCode()); 268 } 269 } 270