// Copyright 2022 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // //////////////////////////////////////////////////////////////////////////////// package com.google.crypto.tink.mac; import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.assertThrows; import com.google.errorprone.annotations.CanIgnoreReturnValue; import java.security.GeneralSecurityException; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; @RunWith(JUnit4.class) public final class AesCmacParametersTest { private static final AesCmacParameters.Variant NO_PREFIX = AesCmacParameters.Variant.NO_PREFIX; private static final AesCmacParameters.Variant TINK = AesCmacParameters.Variant.TINK; private static final AesCmacParameters.Variant LEGACY = AesCmacParameters.Variant.LEGACY; private static final AesCmacParameters.Variant CRUNCHY = AesCmacParameters.Variant.CRUNCHY; @CanIgnoreReturnValue private static AesCmacParameters create( int keySizeBytes, int tagSizeBytes, AesCmacParameters.Variant variant) throws GeneralSecurityException { return AesCmacParameters.builder() .setKeySizeBytes(keySizeBytes) .setTagSizeBytes(tagSizeBytes) .setVariant(variant) .build(); } @CanIgnoreReturnValue private static AesCmacParameters create(int keySizeBytes, int tagSizeBytes) throws GeneralSecurityException { return AesCmacParameters.builder() .setKeySizeBytes(keySizeBytes) .setTagSizeBytes(tagSizeBytes) .build(); } @Test public void testAesCmacParameters_incompleteBuildsFail() throws Exception { assertThrows(GeneralSecurityException.class, () -> AesCmacParameters.builder().build()); assertThrows( GeneralSecurityException.class, () -> AesCmacParameters.builder().setTagSizeBytes(10).build()); assertThrows( GeneralSecurityException.class, () -> AesCmacParameters.builder().setKeySizeBytes(16).build()); } @Test public void testAesCmacParameters_buildWithVariantSetToNull_fails() throws Exception { assertThrows( GeneralSecurityException.class, () -> AesCmacParameters.builder() .setKeySizeBytes(16) .setTagSizeBytes(16) .setVariant(null) .build()); } @Test public void testAesCmacParameters_basic() throws Exception { AesCmacParameters parameters = create(16, 16); assertThat(parameters.getKeySizeBytes()).isEqualTo(16); assertThat(parameters.getCryptographicTagSizeBytes()).isEqualTo(16); assertThat(parameters.getTotalTagSizeBytes()).isEqualTo(16); assertThat(parameters.getVariant()).isEqualTo(NO_PREFIX); assertThat(parameters.hasIdRequirement()).isFalse(); } @Test public void testAesCmacParameters_variant() throws Exception { assertThat(create(16, 16, NO_PREFIX).getVariant()).isEqualTo(NO_PREFIX); assertThat(create(16, 16, TINK).getVariant()).isEqualTo(TINK); assertThat(create(16, 16, LEGACY).getVariant()).isEqualTo(LEGACY); assertThat(create(16, 16, CRUNCHY).getVariant()).isEqualTo(CRUNCHY); } @Test public void testAesCmacParameters_hasIdRequirement() throws Exception { assertThat(create(32, 16, NO_PREFIX).hasIdRequirement()).isFalse(); assertThat(create(32, 16, TINK).hasIdRequirement()).isTrue(); assertThat(create(32, 16, LEGACY).hasIdRequirement()).isTrue(); assertThat(create(32, 16, CRUNCHY).hasIdRequirement()).isTrue(); } @Test public void testAesCmacParameters_createWithDifferentKeySizes() throws Exception { create(16, 13); create(32, 13); assertThrows(GeneralSecurityException.class, () -> create(-2, 13)); assertThrows(GeneralSecurityException.class, () -> create(5, 13)); assertThrows(GeneralSecurityException.class, () -> create(13, 13)); assertThrows(GeneralSecurityException.class, () -> create(20, 13)); assertThrows(GeneralSecurityException.class, () -> create(24, 13)); assertThrows(GeneralSecurityException.class, () -> create(42, 13)); } @Test public void testAesCmacParameters_createForKeysetWithDifferentKeySizes() throws Exception { create(16, 13, LEGACY); create(32, 13, CRUNCHY); assertThrows(GeneralSecurityException.class, () -> create(-2, 13, LEGACY)); assertThrows(GeneralSecurityException.class, () -> create(5, 13, CRUNCHY)); assertThrows(GeneralSecurityException.class, () -> create(13, 13, TINK)); assertThrows(GeneralSecurityException.class, () -> create(20, 13, LEGACY)); assertThrows(GeneralSecurityException.class, () -> create(24, 13, CRUNCHY)); assertThrows(GeneralSecurityException.class, () -> create(42, 13, TINK)); } @Test public void testAesCmacParameters_getKeySizeBytes() throws Exception { assertThat(create(16, 16).getKeySizeBytes()).isEqualTo(16); assertThat(create(32, 16).getKeySizeBytes()).isEqualTo(32); } @Test public void testAesCmacParameters_tagSizesConstruction() throws Exception { assertThrows(GeneralSecurityException.class, () -> create(16, 5)); assertThrows(GeneralSecurityException.class, () -> create(32, 6)); assertThrows(GeneralSecurityException.class, () -> create(16, 7)); assertThrows(GeneralSecurityException.class, () -> create(32, 8)); assertThrows(GeneralSecurityException.class, () -> create(16, 9)); create(16, 10); create(32, 11); create(16, 12); create(32, 13); create(16, 14); create(32, 15); create(16, 16); assertThrows(GeneralSecurityException.class, () -> create(16, 17)); assertThrows(GeneralSecurityException.class, () -> create(32, 18)); assertThrows(GeneralSecurityException.class, () -> create(16, 19)); assertThrows(GeneralSecurityException.class, () -> create(32, 20)); assertThrows(GeneralSecurityException.class, () -> create(16, 21)); assertThrows(GeneralSecurityException.class, () -> create(32, 32)); } @Test public void testAesCmacParameters_tagSizesConstruction2() throws Exception { assertThrows(GeneralSecurityException.class, () -> create(32, 5, TINK)); assertThrows(GeneralSecurityException.class, () -> create(16, 6, TINK)); assertThrows(GeneralSecurityException.class, () -> create(32, 7, TINK)); assertThrows(GeneralSecurityException.class, () -> create(16, 8, TINK)); assertThrows(GeneralSecurityException.class, () -> create(32, 9, TINK)); assertThrows(GeneralSecurityException.class, () -> create(16, 9, CRUNCHY)); assertThrows(GeneralSecurityException.class, () -> create(32, 9, LEGACY)); create(16, 10, TINK); create(32, 10, CRUNCHY); create(16, 10, LEGACY); create(32, 11, TINK); create(16, 12, TINK); create(32, 13, TINK); create(16, 14, TINK); create(32, 15, TINK); create(16, 16, TINK); create(32, 16, CRUNCHY); create(16, 16, LEGACY); assertThrows(GeneralSecurityException.class, () -> create(32, 17, CRUNCHY)); assertThrows(GeneralSecurityException.class, () -> create(16, 17, LEGACY)); assertThrows(GeneralSecurityException.class, () -> create(32, 17, TINK)); assertThrows(GeneralSecurityException.class, () -> create(16, 18, TINK)); assertThrows(GeneralSecurityException.class, () -> create(32, 21, TINK)); assertThrows(GeneralSecurityException.class, () -> create(16, 32, TINK)); } @Test public void testAesCmacParameters_getTotalTagSizeBytes() throws Exception { assertThat(create(16, 10).getTotalTagSizeBytes()).isEqualTo(10); assertThat(create(16, 11).getTotalTagSizeBytes()).isEqualTo(11); assertThat(create(16, 12).getTotalTagSizeBytes()).isEqualTo(12); assertThat(create(16, 13).getTotalTagSizeBytes()).isEqualTo(13); assertThat(create(16, 14).getTotalTagSizeBytes()).isEqualTo(14); assertThat(create(16, 15).getTotalTagSizeBytes()).isEqualTo(15); assertThat(create(16, 16).getTotalTagSizeBytes()).isEqualTo(16); assertThat(create(32, 10, TINK).getTotalTagSizeBytes()).isEqualTo(15); assertThat(create(32, 10, CRUNCHY).getTotalTagSizeBytes()).isEqualTo(15); assertThat(create(32, 10, LEGACY).getTotalTagSizeBytes()).isEqualTo(15); assertThat(create(32, 13, TINK).getTotalTagSizeBytes()).isEqualTo(18); assertThat(create(32, 13, CRUNCHY).getTotalTagSizeBytes()).isEqualTo(18); assertThat(create(32, 13, LEGACY).getTotalTagSizeBytes()).isEqualTo(18); assertThat(create(32, 16, TINK).getTotalTagSizeBytes()).isEqualTo(21); assertThat(create(32, 16, CRUNCHY).getTotalTagSizeBytes()).isEqualTo(21); assertThat(create(32, 16, LEGACY).getTotalTagSizeBytes()).isEqualTo(21); } @Test public void testAesCmacParameters_getCryptographicTagSizeBytes() throws Exception { assertThat(create(16, 10).getCryptographicTagSizeBytes()).isEqualTo(10); assertThat(create(16, 11).getCryptographicTagSizeBytes()).isEqualTo(11); assertThat(create(16, 12).getCryptographicTagSizeBytes()).isEqualTo(12); assertThat(create(16, 13).getCryptographicTagSizeBytes()).isEqualTo(13); assertThat(create(16, 14).getCryptographicTagSizeBytes()).isEqualTo(14); assertThat(create(16, 15).getCryptographicTagSizeBytes()).isEqualTo(15); assertThat(create(16, 16).getCryptographicTagSizeBytes()).isEqualTo(16); assertThat(create(32, 10, TINK).getCryptographicTagSizeBytes()).isEqualTo(10); assertThat(create(32, 10, CRUNCHY).getCryptographicTagSizeBytes()).isEqualTo(10); assertThat(create(32, 10, LEGACY).getCryptographicTagSizeBytes()).isEqualTo(10); assertThat(create(32, 13, TINK).getCryptographicTagSizeBytes()).isEqualTo(13); assertThat(create(32, 13, CRUNCHY).getCryptographicTagSizeBytes()).isEqualTo(13); assertThat(create(32, 13, LEGACY).getCryptographicTagSizeBytes()).isEqualTo(13); assertThat(create(32, 16, TINK).getCryptographicTagSizeBytes()).isEqualTo(16); assertThat(create(32, 16, CRUNCHY).getCryptographicTagSizeBytes()).isEqualTo(16); assertThat(create(32, 16, LEGACY).getCryptographicTagSizeBytes()).isEqualTo(16); } @Test public void testAesCmacParameters_equal() throws Exception { assertThat(create(16, 10)).isEqualTo(create(16, 10, NO_PREFIX)); assertThat(create(32, 11)).isEqualTo(create(32, 11, NO_PREFIX)); assertThat(create(16, 12)).isEqualTo(create(16, 12, NO_PREFIX)); assertThat(create(32, 13)).isEqualTo(create(32, 13, NO_PREFIX)); assertThat(create(16, 13)).isEqualTo(create(16, 13, NO_PREFIX)); assertThat(create(16, 16, TINK)).isEqualTo(create(16, 16, TINK)); assertThat(create(32, 16, LEGACY)).isEqualTo(create(32, 16, LEGACY)); assertThat(create(16, 16, CRUNCHY)).isEqualTo(create(16, 16, CRUNCHY)); } @Test public void testAesCmacParameters_notEqual() throws Exception { assertThat(create(32, 10, NO_PREFIX)).isNotEqualTo(create(16, 10, NO_PREFIX)); assertThat(create(16, 10, NO_PREFIX)).isNotEqualTo(create(16, 11, NO_PREFIX)); assertThat(create(32, 10, NO_PREFIX)).isNotEqualTo(create(32, 10, TINK)); assertThat(create(16, 10, TINK)).isNotEqualTo(create(16, 10, LEGACY)); assertThat(create(32, 10, LEGACY)).isNotEqualTo(create(32, 10, CRUNCHY)); } @Test public void testAesCmacParameters_equalHashes() throws Exception { assertThat(create(16, 10).hashCode()).isEqualTo(create(16, 10, NO_PREFIX).hashCode()); assertThat(create(32, 11).hashCode()).isEqualTo(create(32, 11, NO_PREFIX).hashCode()); assertThat(create(16, 12).hashCode()).isEqualTo(create(16, 12, NO_PREFIX).hashCode()); assertThat(create(32, 13).hashCode()).isEqualTo(create(32, 13, NO_PREFIX).hashCode()); assertThat(create(16, 13).hashCode()).isEqualTo(create(16, 13, NO_PREFIX).hashCode()); assertThat(create(16, 16, TINK).hashCode()).isEqualTo(create(16, 16, TINK).hashCode()); assertThat(create(32, 16, LEGACY).hashCode()).isEqualTo(create(32, 16, LEGACY).hashCode()); assertThat(create(16, 16, CRUNCHY).hashCode()).isEqualTo(create(16, 16, CRUNCHY).hashCode()); } @Test public void testAesCmacParameters_notEqualHashes() throws Exception { assertThat(create(32, 10, NO_PREFIX).hashCode()) .isNotEqualTo(create(16, 10, NO_PREFIX).hashCode()); assertThat(create(16, 10, NO_PREFIX).hashCode()) .isNotEqualTo(create(16, 11, NO_PREFIX).hashCode()); assertThat(create(32, 10, NO_PREFIX).hashCode()).isNotEqualTo(create(32, 10, TINK).hashCode()); assertThat(create(16, 10, TINK).hashCode()).isNotEqualTo(create(16, 10, LEGACY).hashCode()); assertThat(create(32, 10, LEGACY).hashCode()).isNotEqualTo(create(32, 10, CRUNCHY).hashCode()); } }