xref: /aosp_15_r20/external/tink/cc/mac/internal/chunked_mac_impl_test.cc (revision e7b1675dde1b92d52ec075b0a92829627f2c52a5)
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 #include "tink/mac/internal/chunked_mac_impl.h"
18 
19 #include <memory>
20 #include <string>
21 #include <utility>
22 
23 #include "gmock/gmock.h"
24 #include "gtest/gtest.h"
25 #include "tink/chunked_mac.h"
26 #include "tink/subtle/mac/stateful_mac.h"
27 #include "tink/util/status.h"
28 #include "tink/util/statusor.h"
29 #include "tink/util/test_matchers.h"
30 #include "proto/aes_cmac.pb.h"
31 #include "proto/common.pb.h"
32 #include "proto/hmac.pb.h"
33 
34 namespace crypto {
35 namespace tink {
36 namespace internal {
37 namespace {
38 
39 using ::crypto::tink::test::IsOk;
40 using ::crypto::tink::test::IsOkAndHolds;
41 using ::crypto::tink::test::StatusIs;
42 using ::google::crypto::tink::AesCmacKey;
43 using ::google::crypto::tink::AesCmacParams;
44 using ::google::crypto::tink::HashType;
45 using ::google::crypto::tink::HmacKey;
46 using ::google::crypto::tink::HmacParams;
47 using ::testing::_;
48 using ::testing::ByMove;
49 using ::testing::Return;
50 
51 class MockStatefulMac : public subtle::StatefulMac {
52  public:
53   MOCK_METHOD(util::Status, Update, (absl::string_view), (override));
54   MOCK_METHOD(util::StatusOr<std::string>, Finalize, (), (override));
55 };
56 
57 class MockStatefulMacFactory : public subtle::StatefulMacFactory {
58  public:
59   MOCK_METHOD(util::StatusOr<std::unique_ptr<subtle::StatefulMac>>, Create, (),
60               (const, override));
61 };
62 
TEST(ChunkedMacFactoryTest,NewChunkedCmacSucceeds)63 TEST(ChunkedMacFactoryTest, NewChunkedCmacSucceeds) {
64   AesCmacParams params;
65   params.set_tag_size(16);
66   AesCmacKey key;
67   *key.mutable_params() = params;
68 
69   EXPECT_THAT(NewChunkedCmac(key), IsOk());
70 }
71 
TEST(ChunkedMacFactoryTest,NewChunkedCmacWithMissingKeyParamsFails)72 TEST(ChunkedMacFactoryTest, NewChunkedCmacWithMissingKeyParamsFails) {
73   EXPECT_THAT(NewChunkedCmac(AesCmacKey()).status(),
74               StatusIs(absl::StatusCode::kInvalidArgument));
75 }
76 
TEST(ChunkedMacFactoryTest,NewChunkedHmacSucceeds)77 TEST(ChunkedMacFactoryTest, NewChunkedHmacSucceeds) {
78   HmacParams params;
79   params.set_hash(HashType::SHA256);
80   params.set_tag_size(16);
81   HmacKey key;
82   *key.mutable_params() = params;
83 
84   EXPECT_THAT(NewChunkedHmac(key), IsOk());
85 }
86 
TEST(ChunkedMacFactoryTest,NewChunkedHmacWithMissingKeyParamsFails)87 TEST(ChunkedMacFactoryTest, NewChunkedHmacWithMissingKeyParamsFails) {
88   EXPECT_THAT(NewChunkedHmac(HmacKey()).status(),
89               StatusIs(absl::StatusCode::kInvalidArgument));
90 }
91 
TEST(ChunkedMacImplTest,CreateComputationSucceeds)92 TEST(ChunkedMacImplTest, CreateComputationSucceeds) {
93   auto factory = absl::make_unique<MockStatefulMacFactory>();
94   auto stateful_mac = absl::make_unique<MockStatefulMac>();
95   EXPECT_CALL(*factory, Create())
96       .WillOnce(
97           Return(ByMove(util::StatusOr<std::unique_ptr<subtle::StatefulMac>>(
98               std::move(stateful_mac)))));
99   ChunkedMacImpl chunked_mac(std::move(factory));
100 
101   EXPECT_THAT(chunked_mac.CreateComputation(), IsOk());
102 }
103 
TEST(ChunkedMacImplTest,CreateComputationWithFactoryErrorFails)104 TEST(ChunkedMacImplTest, CreateComputationWithFactoryErrorFails) {
105   auto factory = absl::make_unique<MockStatefulMacFactory>();
106   util::StatusOr<std::unique_ptr<subtle::StatefulMac>> error_status =
107       util::Status(absl::StatusCode::kInternal, "Internal error.");
108   EXPECT_CALL(*factory, Create())
109       .WillOnce(Return(ByMove(std::move(error_status))));
110   ChunkedMacImpl chunked_mac(std::move(factory));
111 
112   EXPECT_THAT(chunked_mac.CreateComputation().status(),
113               StatusIs(absl::StatusCode::kInternal));
114 }
115 
TEST(ChunkedMacImplTest,CreateVerificationSucceeds)116 TEST(ChunkedMacImplTest, CreateVerificationSucceeds) {
117   auto factory = absl::make_unique<MockStatefulMacFactory>();
118   auto stateful_mac = absl::make_unique<MockStatefulMac>();
119   EXPECT_CALL(*factory, Create())
120       .WillOnce(
121           Return(ByMove(util::StatusOr<std::unique_ptr<subtle::StatefulMac>>(
122               std::move(stateful_mac)))));
123   ChunkedMacImpl chunked_mac(std::move(factory));
124 
125   EXPECT_THAT(chunked_mac.CreateVerification("tag"), IsOk());
126 }
127 
TEST(ChunkedMacImplTest,CreateVerificationWithFactoryErrorFails)128 TEST(ChunkedMacImplTest, CreateVerificationWithFactoryErrorFails) {
129   auto factory = absl::make_unique<MockStatefulMacFactory>();
130   util::StatusOr<std::unique_ptr<subtle::StatefulMac>> error_status =
131       util::Status(absl::StatusCode::kInternal, "Internal error.");
132   EXPECT_CALL(*factory, Create())
133       .WillOnce(Return(ByMove(std::move(error_status))));
134   ChunkedMacImpl chunked_mac(std::move(factory));
135 
136   EXPECT_THAT(chunked_mac.CreateVerification("tag").status(),
137               StatusIs(absl::StatusCode::kInternal));
138 }
139 
TEST(ChunkedMacComputationImplTest,UpdateSucceeds)140 TEST(ChunkedMacComputationImplTest, UpdateSucceeds) {
141   auto stateful_mac = absl::make_unique<MockStatefulMac>();
142   EXPECT_CALL(*stateful_mac, Update(_)).WillOnce(Return(util::OkStatus()));
143   ChunkedMacComputationImpl mac_computation(std::move(stateful_mac));
144 
145   EXPECT_THAT(mac_computation.Update("data"), IsOk());
146 }
147 
TEST(ChunkedMacComputationImplTest,UpdateFails)148 TEST(ChunkedMacComputationImplTest, UpdateFails) {
149   auto stateful_mac = absl::make_unique<MockStatefulMac>();
150   util::Status error_status =
151       util::Status(absl::StatusCode::kInternal, "Internal error.");
152   EXPECT_CALL(*stateful_mac, Update(_)).WillOnce(Return(error_status));
153   ChunkedMacComputationImpl mac_computation(std::move(stateful_mac));
154 
155   EXPECT_THAT(mac_computation.Update("data"), StatusIs(error_status.code()));
156 }
157 
TEST(ChunkedMacComputationImplTest,OperationsFailAfterComputeMac)158 TEST(ChunkedMacComputationImplTest, OperationsFailAfterComputeMac) {
159   auto stateful_mac = absl::make_unique<MockStatefulMac>();
160   util::StatusOr<std::string> tag = std::string("tag");
161   EXPECT_CALL(*stateful_mac, Finalize()).WillOnce(Return(tag));
162   ChunkedMacComputationImpl mac_computation(std::move(stateful_mac));
163 
164   EXPECT_THAT(mac_computation.ComputeMac(), IsOkAndHolds(*tag));
165 
166   EXPECT_THAT(mac_computation.Update("data"),
167               StatusIs(absl::StatusCode::kFailedPrecondition));
168   EXPECT_THAT(mac_computation.ComputeMac().status(),
169               StatusIs(absl::StatusCode::kFailedPrecondition));
170 }
171 
TEST(ChunkedMacComputationImplTest,ComputeMacSucceeds)172 TEST(ChunkedMacComputationImplTest, ComputeMacSucceeds) {
173   auto stateful_mac = absl::make_unique<MockStatefulMac>();
174   util::StatusOr<std::string> tag = std::string("tag");
175   EXPECT_CALL(*stateful_mac, Finalize()).WillOnce(Return(tag));
176   ChunkedMacComputationImpl mac_computation(std::move(stateful_mac));
177 
178   EXPECT_THAT(mac_computation.ComputeMac(), IsOkAndHolds(*tag));
179 }
180 
TEST(ChunkedMacComputationImplTest,ComputeMacFails)181 TEST(ChunkedMacComputationImplTest, ComputeMacFails) {
182   auto stateful_mac = absl::make_unique<MockStatefulMac>();
183   util::Status error_status =
184       util::Status(absl::StatusCode::kInternal, "Internal error.");
185   EXPECT_CALL(*stateful_mac, Finalize()).WillOnce(Return(error_status));
186   ChunkedMacComputationImpl mac_computation(std::move(stateful_mac));
187 
188   EXPECT_THAT(mac_computation.ComputeMac().status(),
189               StatusIs(error_status.code()));
190 }
191 
TEST(ChunkedMacVerificationImplTest,UpdateSucceeds)192 TEST(ChunkedMacVerificationImplTest, UpdateSucceeds) {
193   auto stateful_mac = absl::make_unique<MockStatefulMac>();
194   EXPECT_CALL(*stateful_mac, Update(_)).WillOnce(Return(util::OkStatus()));
195   ChunkedMacVerificationImpl mac_verification(std::move(stateful_mac), "tag");
196 
197   EXPECT_THAT(mac_verification.Update("data"), IsOk());
198 }
199 
TEST(ChunkedMacVerificationImplTest,UpdateFails)200 TEST(ChunkedMacVerificationImplTest, UpdateFails) {
201   auto stateful_mac = absl::make_unique<MockStatefulMac>();
202   util::Status error_status =
203       util::Status(absl::StatusCode::kInternal, "Internal error.");
204   EXPECT_CALL(*stateful_mac, Update(_)).WillOnce(Return(error_status));
205   ChunkedMacVerificationImpl mac_verification(std::move(stateful_mac), "tag");
206 
207   EXPECT_THAT(mac_verification.Update("data"), StatusIs(error_status.code()));
208 }
209 
TEST(ChunkedMacVerificationImplTest,VerifyMacSucceeds)210 TEST(ChunkedMacVerificationImplTest, VerifyMacSucceeds) {
211   auto stateful_mac = absl::make_unique<MockStatefulMac>();
212   util::StatusOr<std::string> tag = std::string("tag");
213   EXPECT_CALL(*stateful_mac, Finalize()).WillOnce(Return(tag));
214   ChunkedMacVerificationImpl mac_verification(std::move(stateful_mac), *tag);
215 
216   EXPECT_THAT(mac_verification.VerifyMac(), IsOk());
217 }
218 
TEST(ChunkedMacVerificationImplTest,VerifyMacFailsWithInvalidSameLengthTag)219 TEST(ChunkedMacVerificationImplTest, VerifyMacFailsWithInvalidSameLengthTag) {
220   auto stateful_mac = absl::make_unique<MockStatefulMac>();
221   util::StatusOr<std::string> tag = std::string("tag123");
222   EXPECT_CALL(*stateful_mac, Finalize()).WillOnce(Return(tag));
223   ChunkedMacVerificationImpl mac_verification(std::move(stateful_mac),
224                                               "tag456");
225 
226   EXPECT_THAT(mac_verification.VerifyMac(),
227               StatusIs(absl::StatusCode::kInvalidArgument));
228 }
229 
TEST(ChunkedMacVerificationImplTest,VerifyMacFailsWithDifferentLengthTag)230 TEST(ChunkedMacVerificationImplTest, VerifyMacFailsWithDifferentLengthTag) {
231   auto stateful_mac = absl::make_unique<MockStatefulMac>();
232   util::StatusOr<std::string> tag = std::string("tag");
233   EXPECT_CALL(*stateful_mac, Finalize()).WillOnce(Return(tag));
234   ChunkedMacVerificationImpl mac_verification(std::move(stateful_mac),
235                                               "tag456");
236 
237   EXPECT_THAT(mac_verification.VerifyMac(),
238               StatusIs(absl::StatusCode::kInvalidArgument));
239 }
240 
TEST(ChunkedMacVerificationImplTest,VerifyMacFailsWithFinalizeError)241 TEST(ChunkedMacVerificationImplTest, VerifyMacFailsWithFinalizeError) {
242   auto stateful_mac = absl::make_unique<MockStatefulMac>();
243   util::Status error_status =
244       util::Status(absl::StatusCode::kInternal, "Internal error.");
245   EXPECT_CALL(*stateful_mac, Finalize()).WillOnce(Return(error_status));
246   ChunkedMacVerificationImpl mac_verification(std::move(stateful_mac), "tag");
247 
248   EXPECT_THAT(mac_verification.VerifyMac(), StatusIs(error_status.code()));
249 }
250 
TEST(ChunkedMacVerificationImplTest,OperationsFailAfterVerifyMac)251 TEST(ChunkedMacVerificationImplTest, OperationsFailAfterVerifyMac) {
252   auto stateful_mac = absl::make_unique<MockStatefulMac>();
253   util::StatusOr<std::string> tag = std::string("tag");
254   EXPECT_CALL(*stateful_mac, Finalize()).WillOnce(Return(tag));
255   ChunkedMacVerificationImpl mac_verification(std::move(stateful_mac), *tag);
256 
257   EXPECT_THAT(mac_verification.VerifyMac(), IsOk());
258 
259   EXPECT_THAT(mac_verification.Update("data"),
260               StatusIs(absl::StatusCode::kFailedPrecondition));
261   EXPECT_THAT(mac_verification.VerifyMac(),
262               StatusIs(absl::StatusCode::kFailedPrecondition));
263 }
264 
265 }  // namespace
266 }  // namespace internal
267 }  // namespace tink
268 }  // namespace crypto
269