• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.subtle;
18 
19 import static com.google.common.truth.Truth.assertThat;
20 import static org.junit.Assert.assertThrows;
21 import static org.junit.Assume.assumeTrue;
22 
23 import com.google.crypto.tink.Mac;
24 import com.google.crypto.tink.config.TinkFips;
25 import com.google.crypto.tink.config.internal.TinkFipsUtil;
26 import com.google.crypto.tink.mac.internal.AesCmacTestUtil;
27 import com.google.crypto.tink.mac.internal.AesCmacTestUtil.AesCmacTestVector;
28 import com.google.crypto.tink.mac.internal.HmacTestUtil;
29 import com.google.crypto.tink.mac.internal.HmacTestUtil.HmacTestVector;
30 import java.security.GeneralSecurityException;
31 import java.security.Security;
32 import java.util.Arrays;
33 import org.conscrypt.Conscrypt;
34 import org.junit.Assume;
35 import org.junit.BeforeClass;
36 import org.junit.experimental.theories.DataPoints;
37 import org.junit.experimental.theories.FromDataPoints;
38 import org.junit.experimental.theories.Theories;
39 import org.junit.experimental.theories.Theory;
40 import org.junit.runner.RunWith;
41 
42 @RunWith(Theories.class)
43 public class PrfMacTest {
44   @BeforeClass
setUp()45   public static void setUp() throws Exception {
46     // If Tink is built in FIPS-only mode, register Conscrypt for the tests.
47     if (TinkFips.useOnlyFips()) {
48       try {
49         Conscrypt.checkAvailability();
50         Security.addProvider(Conscrypt.newProvider());
51       } catch (Throwable cause) {
52         throw new IllegalStateException(
53             "Cannot test HMAC in FIPS-mode without Conscrypt Provider", cause);
54       }
55     }
56 
57     hmacImplementationTestVectors =
58         Arrays.copyOf(
59             HmacTestUtil.HMAC_TEST_VECTORS,
60             HmacTestUtil.HMAC_TEST_VECTORS.length + HmacTestUtil.PREFIXED_KEY_TYPES.length);
61     System.arraycopy(
62         HmacTestUtil.PREFIXED_KEY_TYPES,
63         0,
64         hmacImplementationTestVectors,
65         HmacTestUtil.HMAC_TEST_VECTORS.length,
66         HmacTestUtil.PREFIXED_KEY_TYPES.length);
67   }
68 
69   @DataPoints("allAesCmacTestVectors")
70   public static final AesCmacTestVector[] CMAC_IMPLEMENTATION_TEST_VECTORS =
71       new AesCmacTestVector[] {
72         AesCmacTestUtil.RFC_TEST_VECTOR_0,
73         AesCmacTestUtil.RFC_TEST_VECTOR_1,
74         AesCmacTestUtil.RFC_TEST_VECTOR_2,
75         AesCmacTestUtil.NOT_OVERFLOWING_INTERNAL_STATE,
76         AesCmacTestUtil.FILL_UP_EXACTLY_INTERNAL_STATE,
77         AesCmacTestUtil.FILL_UP_EXACTLY_INTERNAL_STATE_TWICE,
78         AesCmacTestUtil.OVERFLOW_INTERNAL_STATE_ONCE,
79         AesCmacTestUtil.OVERFLOW_INTERNAL_STATE_TWICE,
80         AesCmacTestUtil.SHORTER_TAG,
81         AesCmacTestUtil.TAG_WITH_KEY_PREFIX_TYPE_LEGACY,
82         AesCmacTestUtil.TAG_WITH_KEY_PREFIX_TYPE_TINK,
83         AesCmacTestUtil.LONG_KEY_TEST_VECTOR,
84       };
85 
86   @DataPoints("failingAesCmacTestVectors")
87   public static final AesCmacTestVector[] CMAC_FAILING_TEST_VECTORS =
88       new AesCmacTestVector[] {
89         AesCmacTestUtil.WRONG_PREFIX_TAG_LEGACY,
90         AesCmacTestUtil.WRONG_PREFIX_TAG_TINK,
91         AesCmacTestUtil.TAG_TOO_SHORT
92       };
93 
94   @DataPoints("failingHmacTestVectors")
95   public static final HmacTestVector[] HMAC_FAILING_TEST_VECTORS =
96       HmacTestUtil.CREATE_VERIFICATION_FAILS_FAST;
97 
98   @DataPoints("allHmacTestVectors")
99   public static HmacTestVector[] hmacImplementationTestVectors;
100 
101   @Theory
computeAesCmac_isCorrect(@romDataPoints"allAesCmacTestVectors") AesCmacTestVector t)102   public void computeAesCmac_isCorrect(@FromDataPoints("allAesCmacTestVectors") AesCmacTestVector t)
103       throws Exception {
104     Assume.assumeFalse(TinkFips.useOnlyFips());
105 
106     Mac aesCmac = PrfMac.create(t.key);
107 
108     assertThat(aesCmac.computeMac(t.message)).isEqualTo(t.tag);
109   }
110 
111   @Theory
verifyAesCmac_isCorrect(@romDataPoints"allAesCmacTestVectors") AesCmacTestVector t)112   public void verifyAesCmac_isCorrect(@FromDataPoints("allAesCmacTestVectors") AesCmacTestVector t)
113       throws Exception {
114     Assume.assumeFalse(TinkFips.useOnlyFips());
115 
116     Mac aesCmac = PrfMac.create(t.key);
117 
118     aesCmac.verifyMac(t.tag, t.message);
119   }
120 
121   @Theory
verifyAesCmac_throwsOnWrongTag( @romDataPoints"failingAesCmacTestVectors") AesCmacTestVector t)122   public void verifyAesCmac_throwsOnWrongTag(
123       @FromDataPoints("failingAesCmacTestVectors") AesCmacTestVector t) throws Exception {
124     Assume.assumeFalse(TinkFips.useOnlyFips());
125 
126     Mac aesCmac = PrfMac.create(t.key);
127 
128     assertThrows(GeneralSecurityException.class, () -> aesCmac.verifyMac(t.tag, t.message));
129   }
130 
131   @Theory
computeHmac_isCorrect(@romDataPoints"allHmacTestVectors") HmacTestVector t)132   public void computeHmac_isCorrect(@FromDataPoints("allHmacTestVectors") HmacTestVector t)
133       throws Exception {
134     assumeTrue(!TinkFips.useOnlyFips() || TinkFipsUtil.fipsModuleAvailable());
135 
136     Mac hmac = PrfMac.create(t.key);
137 
138     assertThat(hmac.computeMac(t.message)).isEqualTo(t.tag);
139   }
140 
141   @Theory
verifyHmac_isCorrect(@romDataPoints"allHmacTestVectors") HmacTestVector t)142   public void verifyHmac_isCorrect(@FromDataPoints("allHmacTestVectors") HmacTestVector t)
143       throws Exception {
144     assumeTrue(!TinkFips.useOnlyFips() || TinkFipsUtil.fipsModuleAvailable());
145 
146     Mac hmac = PrfMac.create(t.key);
147 
148     hmac.verifyMac(t.tag, t.message);
149   }
150 
151   @Theory
verifyHmac_throwsOnWrongTag( @romDataPoints"failingHmacTestVectors") HmacTestVector t)152   public void verifyHmac_throwsOnWrongTag(
153       @FromDataPoints("failingHmacTestVectors") HmacTestVector t) throws Exception {
154     assumeTrue(!TinkFips.useOnlyFips() || TinkFipsUtil.fipsModuleAvailable());
155 
156     Mac hmac = PrfMac.create(t.key);
157 
158     assertThrows(GeneralSecurityException.class, () -> hmac.verifyMac(t.tag, t.message));
159   }
160 }
161