1 // Copyright 2019 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 #include "tink/mac/aes_cmac_key_manager.h"
17
18 #include <memory>
19 #include <string>
20
21 #include "gmock/gmock.h"
22 #include "gtest/gtest.h"
23 #include "tink/chunked_mac.h"
24 #include "tink/mac.h"
25 #include "tink/util/status.h"
26 #include "tink/util/statusor.h"
27 #include "tink/util/test_matchers.h"
28 #include "proto/aes_cmac.pb.h"
29
30 namespace crypto {
31 namespace tink {
32
33 namespace {
34
35 using ::crypto::tink::test::IsOk;
36 using ::google::crypto::tink::AesCmacKey;
37 using ::google::crypto::tink::AesCmacKeyFormat;
38 using ::google::crypto::tink::AesCmacParams;
39 using ::testing::Eq;
40 using ::testing::Not;
41 using ::testing::SizeIs;
42
TEST(AesCmacKeyManagerTest,Basics)43 TEST(AesCmacKeyManagerTest, Basics) {
44 EXPECT_THAT(AesCmacKeyManager().get_version(), Eq(0));
45 EXPECT_THAT(AesCmacKeyManager().get_key_type(),
46 Eq("type.googleapis.com/google.crypto.tink.AesCmacKey"));
47 EXPECT_THAT(AesCmacKeyManager().key_material_type(),
48 Eq(google::crypto::tink::KeyData::SYMMETRIC));
49 }
50
TEST(AesCmacKeyManagerTest,ValidateEmptyKey)51 TEST(AesCmacKeyManagerTest, ValidateEmptyKey) {
52 EXPECT_THAT(AesCmacKeyManager().ValidateKey(AesCmacKey()), Not(IsOk()));
53 }
54
ValidParams()55 AesCmacParams ValidParams() {
56 AesCmacParams params;
57 params.set_tag_size(16);
58 return params;
59 }
60
ValidKeyFormat()61 AesCmacKeyFormat ValidKeyFormat() {
62 AesCmacKeyFormat format;
63 *format.mutable_params() = ValidParams();
64 format.set_key_size(32);
65 return format;
66 }
67
TEST(AesCmacKeyManagerTest,ValidateEmptyKeyFormat)68 TEST(AesCmacKeyManagerTest, ValidateEmptyKeyFormat) {
69 EXPECT_THAT(AesCmacKeyManager().ValidateKeyFormat(AesCmacKeyFormat()),
70 Not(IsOk()));
71 }
72
TEST(AesCmacKeyManagerTest,ValidateSimpleKeyFormat)73 TEST(AesCmacKeyManagerTest, ValidateSimpleKeyFormat) {
74 EXPECT_THAT(AesCmacKeyManager().ValidateKeyFormat(ValidKeyFormat()), IsOk());
75 }
76
TEST(AesCmacKeyManagerTest,ValidateKeyFormatKeySizes)77 TEST(AesCmacKeyManagerTest, ValidateKeyFormatKeySizes) {
78 AesCmacKeyFormat format = ValidKeyFormat();
79
80 format.set_key_size(0);
81 EXPECT_THAT(AesCmacKeyManager().ValidateKeyFormat(format), Not(IsOk()));
82
83 format.set_key_size(1);
84 EXPECT_THAT(AesCmacKeyManager().ValidateKeyFormat(format), Not(IsOk()));
85
86 format.set_key_size(15);
87 EXPECT_THAT(AesCmacKeyManager().ValidateKeyFormat(format), Not(IsOk()));
88
89 format.set_key_size(16);
90 EXPECT_THAT(AesCmacKeyManager().ValidateKeyFormat(format), Not(IsOk()));
91
92 format.set_key_size(17);
93 EXPECT_THAT(AesCmacKeyManager().ValidateKeyFormat(format), Not(IsOk()));
94
95 format.set_key_size(31);
96 EXPECT_THAT(AesCmacKeyManager().ValidateKeyFormat(format), Not(IsOk()));
97
98 format.set_key_size(32);
99 EXPECT_THAT(AesCmacKeyManager().ValidateKeyFormat(format), IsOk());
100
101 format.set_key_size(33);
102 EXPECT_THAT(AesCmacKeyManager().ValidateKeyFormat(format), Not(IsOk()));
103 }
104
TEST(AesCmacKeyManagerTest,ValidateKeyFormatTagSizes)105 TEST(AesCmacKeyManagerTest, ValidateKeyFormatTagSizes) {
106 AesCmacKeyFormat format = ValidKeyFormat();
107
108 format.mutable_params()->set_tag_size(0);
109 EXPECT_THAT(AesCmacKeyManager().ValidateKeyFormat(format), Not(IsOk()));
110
111 format.mutable_params()->set_tag_size(9);
112 EXPECT_THAT(AesCmacKeyManager().ValidateKeyFormat(format), Not(IsOk()));
113
114 format.mutable_params()->set_tag_size(10);
115 EXPECT_THAT(AesCmacKeyManager().ValidateKeyFormat(format), IsOk());
116
117 format.mutable_params()->set_tag_size(11);
118 EXPECT_THAT(AesCmacKeyManager().ValidateKeyFormat(format), IsOk());
119
120 format.mutable_params()->set_tag_size(12);
121 EXPECT_THAT(AesCmacKeyManager().ValidateKeyFormat(format), IsOk());
122
123 format.mutable_params()->set_tag_size(15);
124 EXPECT_THAT(AesCmacKeyManager().ValidateKeyFormat(format), IsOk());
125
126 format.mutable_params()->set_tag_size(16);
127 EXPECT_THAT(AesCmacKeyManager().ValidateKeyFormat(format), IsOk());
128
129 format.mutable_params()->set_tag_size(17);
130 EXPECT_THAT(AesCmacKeyManager().ValidateKeyFormat(format), Not(IsOk()));
131
132 format.mutable_params()->set_tag_size(32);
133 EXPECT_THAT(AesCmacKeyManager().ValidateKeyFormat(format), Not(IsOk()));
134 }
135
TEST(AesCmacKeyManagerTest,CreateKey)136 TEST(AesCmacKeyManagerTest, CreateKey) {
137 AesCmacKeyFormat format = ValidKeyFormat();
138 ASSERT_THAT(AesCmacKeyManager().CreateKey(format), IsOk());
139 AesCmacKey key = AesCmacKeyManager().CreateKey(format).value();
140 EXPECT_THAT(key.version(), Eq(0));
141 EXPECT_THAT(key.key_value(), SizeIs(format.key_size()));
142 EXPECT_THAT(key.params().tag_size(), Eq(format.params().tag_size()));
143 }
144
TEST(AesCmacKeyManagerTest,ValidateKey)145 TEST(AesCmacKeyManagerTest, ValidateKey) {
146 AesCmacKeyFormat format = ValidKeyFormat();
147 AesCmacKey key = AesCmacKeyManager().CreateKey(format).value();
148 EXPECT_THAT(AesCmacKeyManager().ValidateKey(key), IsOk());
149 }
150
TEST(AesCmacKeyManagerTest,ValidateKeyInvalidVersion)151 TEST(AesCmacKeyManagerTest, ValidateKeyInvalidVersion) {
152 AesCmacKeyFormat format = ValidKeyFormat();
153 AesCmacKey key = AesCmacKeyManager().CreateKey(format).value();
154 key.set_version(1);
155 EXPECT_THAT(AesCmacKeyManager().ValidateKey(key), Not(IsOk()));
156 }
157
TEST(AesCmacKeyManagerTest,ValidateKeyShortKey)158 TEST(AesCmacKeyManagerTest, ValidateKeyShortKey) {
159 AesCmacKeyFormat format = ValidKeyFormat();
160 AesCmacKey key = AesCmacKeyManager().CreateKey(format).value();
161 key.set_key_value("0123456789abcdef");
162 EXPECT_THAT(AesCmacKeyManager().ValidateKey(key), Not(IsOk()));
163 }
164
TEST(AesCmacKeyManagerTest,ValidateKeyLongTagSize)165 TEST(AesCmacKeyManagerTest, ValidateKeyLongTagSize) {
166 AesCmacKeyFormat format = ValidKeyFormat();
167 AesCmacKey key = AesCmacKeyManager().CreateKey(format).value();
168 key.mutable_params()->set_tag_size(17);
169 EXPECT_THAT(AesCmacKeyManager().ValidateKey(key), Not(IsOk()));
170 }
171
172
TEST(AesCmacKeyManagerTest,ValidateKeyTooShortTagSize)173 TEST(AesCmacKeyManagerTest, ValidateKeyTooShortTagSize) {
174 AesCmacKeyFormat format = ValidKeyFormat();
175 AesCmacKey key = AesCmacKeyManager().CreateKey(format).value();
176 key.mutable_params()->set_tag_size(9);
177 EXPECT_THAT(AesCmacKeyManager().ValidateKey(key), Not(IsOk()));
178 }
179
TEST(AesCmacKeyManagerTest,GetMacPrimitive)180 TEST(AesCmacKeyManagerTest, GetMacPrimitive) {
181 AesCmacKeyFormat format = ValidKeyFormat();
182 AesCmacKey key = AesCmacKeyManager().CreateKey(format).value();
183 auto manager_mac_or = AesCmacKeyManager().GetPrimitive<Mac>(key);
184 ASSERT_THAT(manager_mac_or, IsOk());
185 auto mac_value_or = manager_mac_or.value()->ComputeMac("some plaintext");
186 ASSERT_THAT(mac_value_or, IsOk());
187
188 auto direct_mac_or = subtle::AesCmacBoringSsl::New(
189 util::SecretDataFromStringView(key.key_value()), key.params().tag_size());
190 ASSERT_THAT(direct_mac_or, IsOk());
191 EXPECT_THAT(
192 direct_mac_or.value()->VerifyMac(mac_value_or.value(), "some plaintext"),
193 IsOk());
194 }
195
TEST(AesCmacKeyManagerTest,GetChunkedMacPrimitive)196 TEST(AesCmacKeyManagerTest, GetChunkedMacPrimitive) {
197 AesCmacKeyFormat format = ValidKeyFormat();
198 AesCmacKey key = AesCmacKeyManager().CreateKey(format).value();
199
200 util::StatusOr<std::unique_ptr<ChunkedMac>> chunked_mac =
201 AesCmacKeyManager().GetPrimitive<ChunkedMac>(key);
202 ASSERT_THAT(chunked_mac, IsOk());
203
204 util::StatusOr<std::unique_ptr<ChunkedMacComputation>> computation =
205 (*chunked_mac)->CreateComputation();
206 ASSERT_THAT(computation, IsOk());
207 ASSERT_THAT((*computation)->Update("abc"), IsOk());
208 ASSERT_THAT((*computation)->Update("xyz"), IsOk());
209 util::StatusOr<std::string> tag = (*computation)->ComputeMac();
210 ASSERT_THAT(tag, IsOk());
211
212 util::StatusOr<std::unique_ptr<ChunkedMacVerification>> verification =
213 (*chunked_mac)->CreateVerification(*tag);
214 ASSERT_THAT(verification, IsOk());
215 ASSERT_THAT((*verification)->Update("abc"), IsOk());
216 ASSERT_THAT((*verification)->Update("xyz"), IsOk());
217 EXPECT_THAT((*verification)->VerifyMac(), IsOk());
218 }
219
TEST(AesCmacKeyManagerTest,MixPrimitives)220 TEST(AesCmacKeyManagerTest, MixPrimitives) {
221 AesCmacKeyFormat format = ValidKeyFormat();
222 AesCmacKey key = AesCmacKeyManager().CreateKey(format).value();
223
224 util::StatusOr<std::unique_ptr<Mac>> mac =
225 AesCmacKeyManager().GetPrimitive<Mac>(key);
226 ASSERT_THAT(mac, IsOk());
227
228 util::StatusOr<std::unique_ptr<ChunkedMac>> chunked_mac =
229 AesCmacKeyManager().GetPrimitive<ChunkedMac>(key);
230 ASSERT_THAT(chunked_mac, IsOk());
231
232 // Compute tag with Mac.
233 util::StatusOr<std::string> tag = (*mac)->ComputeMac("abcxyz");
234 ASSERT_THAT(tag, IsOk());
235
236 // Compute chunked tag with ChunkedMac.
237 util::StatusOr<std::unique_ptr<ChunkedMacComputation>> computation =
238 (*chunked_mac)->CreateComputation();
239 ASSERT_THAT(computation, IsOk());
240 ASSERT_THAT((*computation)->Update("abc"), IsOk());
241 ASSERT_THAT((*computation)->Update("xyz"), IsOk());
242 util::StatusOr<std::string> chunked_tag = (*computation)->ComputeMac();
243 ASSERT_THAT(chunked_tag, IsOk());
244 ASSERT_THAT(*chunked_tag, Eq(*tag)); // Both primitives generated same tag.
245
246 // Verify chunked tag with Mac.
247 ASSERT_THAT((*mac)->VerifyMac(*chunked_tag, "abcxyz"), IsOk());
248
249 // Verify tag with ChunkedMac.
250 util::StatusOr<std::unique_ptr<ChunkedMacVerification>> verification =
251 (*chunked_mac)->CreateVerification(*tag);
252 ASSERT_THAT(verification, IsOk());
253 ASSERT_THAT((*verification)->Update("abc"), IsOk());
254 ASSERT_THAT((*verification)->Update("xyz"), IsOk());
255 EXPECT_THAT((*verification)->VerifyMac(), IsOk());
256 }
257
258 } // namespace
259 } // namespace tink
260 } // namespace crypto
261